pyalex 0.14__py3-none-any.whl → 0.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyalex/__init__.py CHANGED
@@ -27,8 +27,6 @@ from pyalex.api import Subfield
27
27
  from pyalex.api import Subfields
28
28
  from pyalex.api import Topic
29
29
  from pyalex.api import Topics
30
- from pyalex.api import Venue
31
- from pyalex.api import Venues
32
30
  from pyalex.api import Work
33
31
  from pyalex.api import Works
34
32
  from pyalex.api import autocomplete
@@ -46,8 +44,6 @@ __all__ = [
46
44
  "Funders",
47
45
  "Publishers",
48
46
  "Publisher",
49
- "Venues",
50
- "Venue",
51
47
  "Institutions",
52
48
  "Institution",
53
49
  "Concepts",
pyalex/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.14'
16
- __version_tuple__ = version_tuple = (0, 14)
15
+ __version__ = version = '0.15'
16
+ __version_tuple__ = version_tuple = (0, 15)
pyalex/api.py CHANGED
@@ -23,7 +23,7 @@ class AlexConfig(dict):
23
23
  config = AlexConfig(
24
24
  email=None,
25
25
  api_key=None,
26
- user_agent="pyalex/" + __version__,
26
+ user_agent="pyalex/{__version__}",
27
27
  openalex_url="https://api.openalex.org",
28
28
  max_retries=0,
29
29
  retry_backoff_factor=0.1,
@@ -31,12 +31,28 @@ config = AlexConfig(
31
31
  )
32
32
 
33
33
 
34
+ def _quote_oa_value(v):
35
+ """Prepare a value for the OpenAlex API.
36
+
37
+ Applies URL encoding to strings and converts booleans to lowercase strings.
38
+ """
39
+
40
+ # workaround for bug https://groups.google.com/u/1/g/openalex-users/c/t46RWnzZaXc
41
+ if isinstance(v, bool):
42
+ return str(v).lower()
43
+
44
+ if isinstance(v, str):
45
+ return quote_plus(v)
46
+
47
+ return v
48
+
49
+
34
50
  def _flatten_kv(d, prefix=""):
35
51
  if isinstance(d, dict):
36
52
  t = []
37
53
  for k, v in d.items():
38
54
  if isinstance(v, list):
39
- t.extend([f"{prefix}.{k}:{i}" for i in v])
55
+ t.extend([f"{prefix}.{k}:{_quote_oa_value(i)}" for i in v])
40
56
  else:
41
57
  new_prefix = f"{prefix}.{k}" if prefix else f"{k}"
42
58
  x = _flatten_kv(v, prefix=new_prefix)
@@ -44,10 +60,7 @@ def _flatten_kv(d, prefix=""):
44
60
 
45
61
  return ",".join(t)
46
62
  else:
47
- # workaround for bug https://groups.google.com/u/1/g/openalex-users/c/t46RWnzZaXc
48
- d = str(d).lower() if isinstance(d, bool) else d
49
-
50
- return f"{prefix}:{d}"
63
+ return f"{prefix}:{_quote_oa_value(d)}"
51
64
 
52
65
 
53
66
  def _params_merge(params, add_params):
@@ -199,10 +212,11 @@ class BaseOpenAlex:
199
212
 
200
213
  def _full_collection_name(self):
201
214
  if self.params is not None and "q" in self.params.keys():
202
- base_url = config.openalex_url + "/autocomplete/"
203
- return base_url + self.__class__.__name__.lower()
215
+ return (
216
+ f"{config.openalex_url}/autocomplete/{self.__class__.__name__.lower()}"
217
+ )
204
218
  else:
205
- return config.openalex_url + "/" + self.__class__.__name__.lower()
219
+ return f"{config.openalex_url}/{self.__class__.__name__.lower()}"
206
220
 
207
221
  def __getattr__(self, key):
208
222
  if key == "groupby":
@@ -223,7 +237,7 @@ class BaseOpenAlex:
223
237
  return self._get_multi_items(record_id)
224
238
 
225
239
  return self._get_from_url(
226
- self._full_collection_name() + "/" + record_id, return_meta=False
240
+ f"{self._full_collection_name()}/{record_id}", return_meta=False
227
241
  )
228
242
 
229
243
  @property
@@ -236,15 +250,14 @@ class BaseOpenAlex:
236
250
  if v is None:
237
251
  pass
238
252
  elif isinstance(v, list):
239
- v_quote = [quote_plus(q) for q in v]
240
- l_params.append(k + "=" + ",".join(v_quote))
253
+ l_params.append("{}={}".format(k, ",".join(map(_quote_oa_value, v))))
241
254
  elif k in ["filter", "sort"]:
242
- l_params.append(k + "=" + _flatten_kv(v))
255
+ l_params.append(f"{k}={_flatten_kv(v)}")
243
256
  else:
244
- l_params.append(k + "=" + quote_plus(str(v)))
257
+ l_params.append(f"{k}={_quote_oa_value(v)}")
245
258
 
246
259
  if l_params:
247
- return self._full_collection_name() + "?" + "&".join(l_params)
260
+ return "{}?{}".format(self._full_collection_name(), "&".join(l_params))
248
261
 
249
262
  return self._full_collection_name()
250
263
 
@@ -294,6 +307,8 @@ class BaseOpenAlex:
294
307
 
295
308
  def paginate(self, method="cursor", page=1, per_page=None, cursor="*", n_max=10000):
296
309
  if method == "cursor":
310
+ if self.params.get("sample"):
311
+ raise ValueError("method should be 'page' when using sample")
297
312
  value = cursor
298
313
  elif method == "page":
299
314
  value = page
@@ -464,50 +479,31 @@ class autocompletes(BaseOpenAlex):
464
479
 
465
480
  def __getitem__(self, key):
466
481
  return self._get_from_url(
467
- config.openalex_url + "/autocomplete" + "?q=" + key, return_meta=False
482
+ f"{config.openalex_url}/autocomplete?q={key}", return_meta=False
468
483
  )
469
484
 
470
485
 
471
- def Venue(*args, **kwargs): # deprecated
472
- # warn about deprecation
473
- warnings.warn(
474
- "Venue is deprecated. Use Sources instead.",
475
- DeprecationWarning,
476
- stacklevel=2,
477
- )
478
-
479
- return Source(*args, **kwargs)
480
-
481
-
482
- def Venues(*args, **kwargs): # deprecated
483
- # warn about deprecation
484
- warnings.warn(
485
- "Venues is deprecated. Use Sources instead.",
486
- DeprecationWarning,
487
- stacklevel=2,
488
- )
489
-
490
- return Sources(*args, **kwargs)
491
-
492
-
493
486
  class Concept(OpenAlexEntity):
494
- # warn about deprecation
495
- warnings.warn(
496
- "Concept is deprecated by OpenAlex and replaced by topics.",
497
- DeprecationWarning,
498
- stacklevel=2,
499
- )
487
+ def __init__(self, *args, **kwargs):
488
+ warnings.warn(
489
+ "Concept is deprecated by OpenAlex and replaced by topics.",
490
+ DeprecationWarning,
491
+ stacklevel=2,
492
+ )
493
+ super().__init__(*args, **kwargs)
500
494
 
501
495
 
502
496
  class Concepts(BaseOpenAlex):
503
- # warn about deprecation
504
- warnings.warn(
505
- "Concepts is deprecated by OpenAlex and replaced by topics.",
506
- DeprecationWarning,
507
- stacklevel=2,
508
- )
509
497
  resource_class = Concept
510
498
 
499
+ def __init__(self, *args, **kwargs):
500
+ warnings.warn(
501
+ "Concepts is deprecated by OpenAlex and replaced by topics.",
502
+ DeprecationWarning,
503
+ stacklevel=2,
504
+ )
505
+ super().__init__(*args, **kwargs)
506
+
511
507
 
512
508
  def autocomplete(s):
513
509
  """autocomplete with any type of entity"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyalex
3
- Version: 0.14
3
+ Version: 0.15
4
4
  Summary: Python interface to the OpenAlex database
5
5
  Author-email: Jonathan de Bruin <jonathandebruinos@gmail.com>
6
6
  License: MIT
@@ -123,7 +123,7 @@ Works()["W2741809807"]["open_access"]
123
123
  {'is_oa': True, 'oa_status': 'gold', 'oa_url': 'https://doi.org/10.7717/peerj.4375'}
124
124
  ```
125
125
 
126
- The previous works also for Authors, Venues, Institutions, Concepts and Topics
126
+ The previous works also for Authors, Sources, Institutions, Concepts and Topics
127
127
 
128
128
  ```python
129
129
  Authors()["A2887243803"]
@@ -441,9 +441,6 @@ pyalex.config.api_key = "<MY_KEY>"
441
441
 
442
442
  ## Alternatives
443
443
 
444
- [Diophila](https://github.com/smierz/diophila) is a nice Python wrapper for OpenAlex. It takes a slightly
445
- different approach, especially interesting to those who don't like the pipe operations.
446
-
447
444
  R users can use the excellent [OpenAlexR](https://github.com/ropensci/openalexR) library.
448
445
 
449
446
  ## License
@@ -0,0 +1,8 @@
1
+ pyalex/__init__.py,sha256=52XK8om6IVD1Yiq_HYOCR6PUY56sPRHutGM03NOrGMQ,1467
2
+ pyalex/_version.py,sha256=poZz4oZoUd1b8WrBvqHJC0SHzGSqhHsFiUSMJDd_Hcw,408
3
+ pyalex/api.py,sha256=IhqRtjy5LtlYffjaHWxRBmKPSIaaXbGqt8qYhKo9YbE,13235
4
+ pyalex-0.15.dist-info/LICENSE,sha256=Mhf5MImRYP06a1EPVJCpkpTstOOEfGajN3T_Fz4izMg,1074
5
+ pyalex-0.15.dist-info/METADATA,sha256=pkDIkcjUnuqePUCdNdXZeRouKh9p16s5g0N0rcYhXxc,13583
6
+ pyalex-0.15.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
7
+ pyalex-0.15.dist-info/top_level.txt,sha256=D0An8hWy9e0xPhTaT6K-yuJKVeVV3bYGxZ6Y-v2WXSU,7
8
+ pyalex-0.15.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (72.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,8 +0,0 @@
1
- pyalex/__init__.py,sha256=EL6oh0vQdSNyvsrxFFgmDn-P_Dgev1IYpP-WiLBxjS8,1553
2
- pyalex/_version.py,sha256=lmFPHiet63Bn9h104yd9q0T6i7C2c0WCbizqrpAtSuk,408
3
- pyalex/api.py,sha256=whUv8TbnW968wlR8U4O-lWsaFHRgW0Ham0cznbR3Zlc,13212
4
- pyalex-0.14.dist-info/LICENSE,sha256=Mhf5MImRYP06a1EPVJCpkpTstOOEfGajN3T_Fz4izMg,1074
5
- pyalex-0.14.dist-info/METADATA,sha256=3bjn78df3VlosFCcseDGs5tfTUIAgCStI_uGjqHT69w,13777
6
- pyalex-0.14.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
7
- pyalex-0.14.dist-info/top_level.txt,sha256=D0An8hWy9e0xPhTaT6K-yuJKVeVV3bYGxZ6Y-v2WXSU,7
8
- pyalex-0.14.dist-info/RECORD,,
File without changes