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
20 changes: 4 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,22 +466,10 @@ import pyalex
pyalex.config.api_key = "<MY_KEY>"
```

To check out whether your API key is indeed working, you can use the following code:

```python
import requests
pyalex.config.retry_http_codes = None
try:
pyalex.Works().filter(from_updated_date="2023-01-12").get()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 403:
logging.info("API key is NOT working 🔴")
else:
logging.error(f"Unexpected HTTP error: {e}")
raise
else:
logging.info("API key is working 👍")
```
pyalex will automatically check whether your API key is valid and throw a `ValueError` if it isn't.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, OpenAlex should check this server-side and raise an error if the key is not valid. I propose to file an issue in their issue tracker.

I propose to remove this logic here because it's implicit, which is not very Pythonic.


If you want to manually check whether the API key is valid, call `pyalex._check_api_key()`
which will return True if it is valid and False if it isn't.

## Alternatives

Expand Down
2 changes: 2 additions & 0 deletions pyalex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from pyalex.api import Topics
from pyalex.api import Work
from pyalex.api import Works
from pyalex.api import _check_api_key
from pyalex.api import autocomplete
from pyalex.api import config
from pyalex.api import invert_abstract
Expand Down Expand Up @@ -63,4 +64,5 @@
"config",
"invert_abstract",
"OpenAlexResponseList",
"_check_api_key",
]
56 changes: 42 additions & 14 deletions pyalex/api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import datetime
import logging
import warnings
from dataclasses import dataclass
from dataclasses import field
from urllib.parse import quote_plus
from urllib.parse import urlunparse

Expand All @@ -13,7 +16,12 @@
__version__ = "0.0.0"


class AlexConfig(dict):
def _check_api_key():
raise NotImplementedError()


@dataclass
class AlexConfig:
"""Configuration class for OpenAlex API.

Attributes
Expand All @@ -34,22 +42,21 @@ class AlexConfig(dict):
List of HTTP status codes to retry on.
"""

def __getattr__(self, key):
return super().__getitem__(key)
email: str | None = None
user_agent: str = f"pyalex/{__version__}"
openalex_url: str = "https://api.openalex.org"
max_retries: int = 0
retry_backoff_factor: float = 0.1
retry_http_codes: list[int] = field(default_factory=lambda: [429, 500, 503])
api_key: str | None = None

def __setattr__(self, key, value):
return super().__setitem__(key, value)
def __setattr__(self, prop, val):
super().__setattr__(prop, val)
if prop == "api_key" and val and not _check_api_key():
raise ValueError("Invalid API key. Please check your OpenAlex API key.")


config = AlexConfig(
email=None,
api_key=None,
user_agent=f"pyalex/{__version__}",
openalex_url="https://api.openalex.org",
max_retries=0,
retry_backoff_factor=0.1,
retry_http_codes=[429, 500, 503],
)
config = AlexConfig()


class or_(dict):
Expand Down Expand Up @@ -1094,3 +1101,24 @@ def autocomplete(s):
# aliases
People = Authors
Journals = Sources


def _check_api_key():
"""Check if the API key is valid."""
bk_cods = config.retry_http_codes
config.retry_http_codes = None
dt = f"{datetime.datetime.now().year}-01-01"
res = None
try:
Works().filter(from_updated_date=dt).get()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 403:
res = False
else:
logging.error(f"Unexpected HTTP error: {e}")
raise
else:
res = True
finally:
config.retry_http_codes = bk_cods
return res
Comment on lines +1106 to +1124
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this function. I propose the following API:

from pyalex.utils import check_api_key

check_api_key()
# raises ValueError if incorrect, returns None if valid. 

This way, we separate our custom logics from the pure wrapper.

Loading