antelope-interface 0.3.3__tar.gz → 0.3.4__tar.gz

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.
Files changed (44) hide show
  1. {antelope_interface-0.3.3/src/antelope_interface.egg-info → antelope_interface-0.3.4}/PKG-INFO +2 -2
  2. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/pyproject.toml +2 -2
  3. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/setup.py +3 -0
  4. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/__init__.py +2 -1
  5. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/models/__init__.py +3 -0
  6. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/models/auth.py +9 -1
  7. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/process_ref.py +8 -8
  8. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/xdb_tokens.py +12 -1
  9. {antelope_interface-0.3.3 → antelope_interface-0.3.4/src/antelope_interface.egg-info}/PKG-INFO +2 -2
  10. antelope_interface-0.3.4/src/antelope_interface.egg-info/requires.txt +2 -0
  11. antelope_interface-0.3.3/src/antelope_interface.egg-info/requires.txt +0 -2
  12. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/LICENSE +0 -0
  13. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/MANIFEST.in +0 -0
  14. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/README.md +0 -0
  15. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/setup.cfg +0 -0
  16. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/exchanges_from_spreadsheet.py +0 -0
  17. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/flows/__init__.py +0 -0
  18. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/flows/flow.py +0 -0
  19. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/flows/flow_interface.py +0 -0
  20. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/flows/openlca_locales.json +0 -0
  21. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/__init__.py +0 -0
  22. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/abstract_query.py +0 -0
  23. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/ibackground.py +0 -0
  24. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/ibasic.py +0 -0
  25. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/iconfigure.py +0 -0
  26. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/iexchange.py +0 -0
  27. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/iforeground.py +0 -0
  28. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/iindex.py +0 -0
  29. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/interfaces/iquantity.py +0 -0
  30. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/models/comparators.py +0 -0
  31. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/qdb/__init__.py +0 -0
  32. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/qdb/qdb.py +0 -0
  33. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/qdb/units.py +0 -0
  34. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/__init__.py +0 -0
  35. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/base.py +0 -0
  36. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/catalog_ref.py +0 -0
  37. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/exchange_ref.py +0 -0
  38. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/flow_ref.py +0 -0
  39. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/quantity_ref.py +0 -0
  40. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/tests/__init__.py +0 -0
  41. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope/refs/tests/test_flows.py +0 -0
  42. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope_interface.egg-info/SOURCES.txt +0 -0
  43. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope_interface.egg-info/dependency_links.txt +0 -0
  44. {antelope_interface-0.3.3 → antelope_interface-0.3.4}/src/antelope_interface.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: antelope_interface
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: A common interface for accessing LCA data
5
5
  Author-email: Brandon Kuczenski <bkuczenski@ucsb.edu>
6
6
  License: BSD-3-Clause
@@ -15,7 +15,7 @@ Classifier: Topic :: Scientific/Engineering
15
15
  Requires-Python: >=3.6
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: synonym_dict>=0.2.4
18
+ Requires-Dist: synonym_dict>=0.2.5
19
19
  Requires-Dist: pydantic>=2.5.0
20
20
  Dynamic: license-file
21
21
 
@@ -21,8 +21,8 @@ classifiers = [
21
21
  "Programming Language :: Python :: 3",
22
22
  "Topic :: Scientific/Engineering"
23
23
  ]
24
- dependencies = ["synonym_dict >= 0.2.4", "pydantic >= 2.5.0"]
25
- version = "0.3.3"
24
+ dependencies = ["synonym_dict >= 0.2.5", "pydantic >= 2.5.0"]
25
+ version = "0.3.4"
26
26
 
27
27
  [tool.setuptools.packages.find]
28
28
  where = ["src"]
@@ -5,6 +5,9 @@ setup()
5
5
 
6
6
  """
7
7
  Version History:
8
+ 0.3.4 2026/03/31 - add 'dash' interface type; add 'grant_add' to XDB tokens
9
+
10
+ 0.3.3.1 - sanitize process reference exchange in entity model; cached basic queries
8
11
  0.3.3 2025/09/08 - Apply ordering to exchange refs; pandas-friendly output for process refs
9
12
 
10
13
  0.3.2 2025/08/01 - 0.3.2 release. better background handling.
@@ -58,9 +58,10 @@ class BasicQuery(BasicInterface, IndexInterface, ExchangeInterface, QuantityInte
58
58
  - archive.source: returns the physical source (or URI) for the archive's content
59
59
 
60
60
  """
61
- def __init__(self, archive, debug=False):
61
+ def __init__(self, archive, debug=False, cached=True):
62
62
  self._archive = archive
63
63
  self._dbg = debug
64
+ self.cached = cached
64
65
 
65
66
  def _perform_query(self, itype, attrname, exc, *args, **kwargs):
66
67
  if itype is None:
@@ -77,6 +77,9 @@ class Entity(EntityRef):
77
77
  properties=dict())
78
78
  for k in entity.signature_fields():
79
79
  ent.properties[k] = entity[k]
80
+ if entity.entity_type == 'process':
81
+ ent.properties['referenceExchange'] = [ReferenceExchange.from_exchange(x) for x in
82
+ entity['referenceExchange']]
80
83
  return ent
81
84
 
82
85
  @classmethod
@@ -15,6 +15,7 @@ class AuthModel(BaseModel):
15
15
 
16
16
 
17
17
  JWT_SCOPES = {
18
+ 'das': 'dash',
18
19
  'bas': 'basic',
19
20
  'ind': 'index',
20
21
  'exc': 'exchange',
@@ -29,7 +30,7 @@ class AuthorizationGrant(AuthModel):
29
30
  This class stands alone as a list of authorizations granted to users. There is no requirement that the
30
31
  users exist in a database
31
32
 
32
- One natural way to use this is to grant users JWTs as bearer tokensusing an oauth2 system- the bearer token
33
+ One natural way to use this is to grant users JWTs as bearer tokens using an oauth2 system- the bearer token
33
34
  would be created + signed by an auth server, and include the grants embedded in the token. In the future, this
34
35
  token could list specific entities the user has a right to access (e.g. per ecoinvent). The problem is that
35
36
  entity UUIDs are 36 characters long- this would become cumbersome if the user had access to
@@ -130,4 +131,11 @@ class AuthorizationGrant(AuthModel):
130
131
 
131
132
  grants.append(cls(user=user, issuer=issuer, origin=origin, access=access, values=values, update=update))
132
133
 
134
+ if jwt.add:
135
+ # grant_add terms show up as access strings in origin-less grants
136
+ # double-loop, parsing over ' ' then ':' just like above
137
+ for a in jwt.add.split(' '):
138
+ for b in a.split(':'):
139
+ grants.append(cls(user=user, issuer=issuer, origin='*', access=b))
140
+
133
141
  return grants
@@ -342,11 +342,11 @@ class ProcessRef(EntityRef):
342
342
  ref_flow = self._use_ref_exch(ref_flow)
343
343
  return self._query.deep_lcia(self.external_ref, lcia_qty, ref_flow=ref_flow, detailed=detailed, **kwargs)
344
344
 
345
- @property
346
- def inventory_as_series(self):
345
+ def inventory_as_series(self, ref_flow=None):
347
346
  """
348
347
  Use this as generative input to pandas.Series:
349
- s = pandas.Series(process_ref.inventory_as_series)
348
+ s = pandas.Series(process_ref.inventory_as_series())
349
+ for processes with multiple references, specify ref_flow as an argument
350
350
  :return:
351
351
  """
352
352
  def _tx_cx(_ex):
@@ -358,19 +358,19 @@ class ProcessRef(EntityRef):
358
358
  return _ex.termination.name
359
359
  else:
360
360
  return None
361
- return {(k.flow.name, _tx_cx(k), k.direction, k.unit): k.value for k in self.inventory()}
361
+ return {(k.flow.name, _tx_cx(k), k.direction, k.unit): k.value for k in self.inventory(ref_flow)}
362
362
 
363
- @property
364
- def inventory_as_dataframe(self):
363
+ def inventory_as_dataframe(self, ref_flow=None):
365
364
  """
366
365
  Use this as generative input to pandas.DataFrame:
367
- df = pandas.DataFrame(process_ref.inventory_as_dataframe)
366
+ df = pandas.DataFrame(process_ref.inventory_as_dataframe())
367
+ for processes with multiple references, specify ref_flow as an argument
368
368
  :return:
369
369
  """
370
370
  def _cx_of(_ex):
371
371
  if _ex.type == 'context':
372
372
  return _ex.termination.name
373
373
  return None
374
- for k in self.inventory():
374
+ for k in self.inventory(ref_flow):
375
375
  yield {'Flow': k.flow.name, 'Direction': k.direction, 'Type': k.type, 'Unit': k.flow.unit,
376
376
  'Value': k.value, 'Context': _cx_of(k)}
@@ -39,6 +39,8 @@ class GrantSpec(BaseModel):
39
39
  qdb: bool # whether requests can be forwarded to qdb
40
40
  values: bool # whether numerical data can be requested
41
41
  update: bool # whether user may alter the resource
42
+ one_time: bool # whether the grant is revoked after first use
43
+ grant_add: Optional[str] = None
42
44
  has_quota: bool # whether user's activities are quota constrained (if true, xdb sends a receipt to auth server for every query)
43
45
 
44
46
  def serialize(self):
@@ -70,6 +72,7 @@ class JwtGrant(BaseModel):
70
72
  exp: int # required
71
73
 
72
74
  grants: str # specifies origins and permissions
75
+ add: Optional[str] = None # space-separated list of "grant_add" strings
73
76
 
74
77
  @classmethod
75
78
  def from_grants(cls, grants: List[GrantSpec], issuer: str):
@@ -82,6 +85,7 @@ class JwtGrant(BaseModel):
82
85
 
83
86
  origins = defaultdict(set)
84
87
  users = set()
88
+ add = list()
85
89
  qdb = False
86
90
  dur = None
87
91
  for g in grants:
@@ -93,6 +97,8 @@ class JwtGrant(BaseModel):
93
97
  dur = g.grant_duration
94
98
  else:
95
99
  dur = min([dur, g.grant_duration])
100
+ if g.grant_add:
101
+ add.append(g.grant_add)
96
102
 
97
103
  if len(users) != 1:
98
104
  raise ValueError('Grants for multiple users received: %s' % users)
@@ -109,7 +115,12 @@ class JwtGrant(BaseModel):
109
115
  the_grants = ' '.join(str_grants)
110
116
  exp = datetime.now() + timedelta(seconds=dur)
111
117
 
112
- return cls(iss=issuer, sub=user, exp=int(exp.timestamp()), grants=the_grants)
118
+ if len(add) > 0:
119
+ grant_add = ' '.join(add)
120
+ else:
121
+ grant_add = None
122
+
123
+ return cls(iss=issuer, sub=user, exp=int(exp.timestamp()), grants=the_grants, add=grant_add)
113
124
 
114
125
 
115
126
  class IssuerKey(BaseModel):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: antelope_interface
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: A common interface for accessing LCA data
5
5
  Author-email: Brandon Kuczenski <bkuczenski@ucsb.edu>
6
6
  License: BSD-3-Clause
@@ -15,7 +15,7 @@ Classifier: Topic :: Scientific/Engineering
15
15
  Requires-Python: >=3.6
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: synonym_dict>=0.2.4
18
+ Requires-Dist: synonym_dict>=0.2.5
19
19
  Requires-Dist: pydantic>=2.5.0
20
20
  Dynamic: license-file
21
21
 
@@ -0,0 +1,2 @@
1
+ synonym_dict>=0.2.5
2
+ pydantic>=2.5.0
@@ -1,2 +0,0 @@
1
- synonym_dict>=0.2.4
2
- pydantic>=2.5.0