ledgerdata 0.1.0.dev6__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.
ledgerdata/__init__.py ADDED
@@ -0,0 +1,15 @@
1
+ """
2
+ Set up module access for the base package
3
+ """
4
+
5
+ from .actors import Actors
6
+ from .client import Client
7
+ from .datasource import Datasource
8
+ from .emissions import Emissions
9
+ from .gdp import GDP
10
+ from .initiatives import Initiatives
11
+ from .population import Population
12
+ from .sector import Sector
13
+ from .targets import Targets
14
+
15
+ __all__ = ["GDP", "Actors", "Client", "Datasource", "Emissions", "Initiatives", "Population", "Sector", "Targets"]
ledgerdata/actors.py ADDED
@@ -0,0 +1,204 @@
1
+ import warnings
2
+
3
+ import httpx
4
+ import requests
5
+ from pydantic.dataclasses import dataclass
6
+
7
+ from .base import Base
8
+
9
+
10
+ @dataclass
11
+ class Actors(Base):
12
+ """Provides methods to retrieve actor and actor-part data from the LEDGER API."""
13
+
14
+ def get_all_actors(self, *args, **kwargs):
15
+ """Retrieve all actors.
16
+
17
+ Sends a GET request to the `/actors` endpoint and returns the response
18
+ as a JSON dictionary.
19
+
20
+ Returns:
21
+ dict: A JSON response containing actor data.
22
+ """
23
+ endpoint = "/actor"
24
+ url = f"{self.server}{endpoint}"
25
+ headers = {"Accept": "application/json"}
26
+ # Add query parameters as a dict
27
+ response = requests.get(url, headers=headers).json()
28
+ # data_list = response.get("data", None)
29
+ return response
30
+
31
+ def parts_of_actor(self, actor_id=str, type: str | None = None, *args, **kwargs):
32
+ """Retrieve parts (sub-actors) of a given actor.
33
+
34
+ Sends a GET request to the `/parts_of/{actor_id}` endpoint and returns
35
+ the response as a JSON dictionary.
36
+
37
+ Args:
38
+ actor_id (str): The code for the actor whose parts you want to retrieve.
39
+ type (Optional[str]): Optional filter for part type.
40
+ *args: Additional positional arguments (currently unused).
41
+ **kwargs: Additional keyword arguments (currently unused).
42
+
43
+ Returns:
44
+ dict: A JSON response containing actor-part data.
45
+ """
46
+ endpoint = f"/actor/{actor_id}/parts"
47
+ url = f"{self.server}{endpoint}"
48
+ headers = {"Accept": "application/json"}
49
+ params = {"type": type} if type else {}
50
+ response = requests.get(url, headers=headers, params=params).json()
51
+ # data_list = response.get("data", None)
52
+ return response
53
+
54
+ def population(self, actor_id=str, *args, **kwargs):
55
+ """Retrieve actor population
56
+
57
+ Sends a GET request to the `/actor/{actor_id}/population` endpoint and returns
58
+ the response as a JSON dictionary.
59
+
60
+ Args:
61
+ actor_id (str): The code for the actor whose parts you want to retrieve.
62
+ *args: Additional positional arguments (currently unused).
63
+ **kwargs: Additional keyword arguments (currently unused).
64
+
65
+ Returns:
66
+ dict: A JSON response containing actor-part data.
67
+ """
68
+ endpoint = f"/actor/{actor_id}/population"
69
+ url = f"{self.server}{endpoint}"
70
+ headers = {"Accept": "application/json"}
71
+ response = requests.get(url, headers=headers).json()
72
+ return response
73
+
74
+ def gdp(self, actor_id=str, *args, **kwargs):
75
+ """Retrieve actor population
76
+
77
+ Sends a GET request to the `/actor/{actor_id}/gdp` endpoint and returns
78
+ the response as a JSON dictionary.
79
+
80
+ Args:
81
+ actor_id (str): The code for the actor whose parts you want to retrieve.
82
+ *args: Additional positional arguments (currently unused).
83
+ **kwargs: Additional keyword arguments (currently unused).
84
+
85
+ Returns:
86
+ dict: A JSON response containing actor-part data.
87
+ """
88
+ endpoint = f"/actor/{actor_id}/gdp"
89
+ url = f"{self.server}{endpoint}"
90
+ headers = {"Accept": "application/json"}
91
+ response = requests.get(url, headers=headers).json()
92
+ return response
93
+
94
+ def energy_consumption(self, actor_id=str, *args, **kwargs):
95
+ """Retrieve actor population
96
+
97
+ Sends a GET request to the `/actor/{actor_id}/energy_consumption` endpoint and returns
98
+ the response as a JSON dictionary.
99
+
100
+ Args:
101
+ actor_id (str): The code for the actor whose parts you want to retrieve.
102
+ *args: Additional positional arguments (currently unused).
103
+ **kwargs: Additional keyword arguments (currently unused).
104
+
105
+ Returns:
106
+ dict: A JSON response containing actor-part data.
107
+ """
108
+ endpoint = f"/actor/{actor_id}/energy_consumption"
109
+ url = f"{self.server}{endpoint}"
110
+ headers = {"Accept": "application/json"}
111
+ response = requests.get(url, headers=headers).json()
112
+ return response
113
+
114
+ def targets(self, actor_id=str, *args, **kwargs):
115
+ """Retrieve actor population
116
+
117
+ Sends a GET request to the `/actor/{actor_id}/targets` endpoint and returns
118
+ the response as a JSON dictionary.
119
+
120
+ Args:
121
+ actor_id (str): The code for the actor whose parts you want to retrieve.
122
+ *args: Additional positional arguments (currently unused).
123
+ **kwargs: Additional keyword arguments (currently unused).
124
+
125
+ Returns:
126
+ dict: A JSON response containing actor-part data.
127
+ """
128
+ endpoint = f"/actor/{actor_id}/targets"
129
+ url = f"{self.server}{endpoint}"
130
+ headers = {"Accept": "application/json"}
131
+ response = requests.get(url, headers=headers).json()
132
+ return response
133
+
134
+ def emissions(self, actor_id=str, ignore_warnings: bool = False, *args, **kwargs):
135
+ """Retrieve actor population
136
+
137
+ Sends a GET request to the `/actor/{actor_id}/emissions` endpoint and returns
138
+ the response as a JSON dictionary.
139
+
140
+ Args:
141
+ actor_id (str): The code for the actor whose parts you want to retrieve.
142
+ *args: Additional positional arguments (currently unused).
143
+ **kwargs: Additional keyword arguments (currently unused).
144
+
145
+ Returns:
146
+ dict: A JSON response containing actor-part data.
147
+ """
148
+ (
149
+ warnings.simplefilter("ignore")
150
+ if ignore_warnings
151
+ else warnings.simplefilter("default")
152
+ )
153
+ endpoint = f"/actor/{actor_id}/emissions"
154
+ url = f"{self.server}{endpoint}"
155
+ headers = {"Accept": "application/json"}
156
+ response = requests.get(url, headers=headers).json()
157
+ return response
158
+
159
+
160
+ def emissions_total_sector(self, actor_id=str, ignore_warnings: bool = False, *args, **kwargs):
161
+ """Retrieve actor population
162
+
163
+ Sends a GET request to the `/actor/{actor_id}/emissions_total_sector` endpoint and returns
164
+ the response as a JSON dictionary.
165
+
166
+ Args:
167
+ actor_id (str): The code for the actor whose parts you want to retrieve.
168
+ *args: Additional positional arguments (currently unused).
169
+ **kwargs: Additional keyword arguments (currently unused).
170
+
171
+ Returns:
172
+ dict: A JSON response containing actor-part data.
173
+ """
174
+ (
175
+ warnings.simplefilter("ignore")
176
+ if ignore_warnings
177
+ else warnings.simplefilter("default")
178
+ )
179
+ endpoint = f"/actor/{actor_id}/emissions_total_sector"
180
+ url = f"{self.server}{endpoint}"
181
+ headers = {"Accept": "application/json"}
182
+ response = requests.get(url, headers=headers).json()
183
+ return response
184
+
185
+ async def emissions_async(
186
+ self, actor_id: str, ignore_warnings: bool = False, *args, **kwargs
187
+ ):
188
+ """Retrieve actor emissions asynchronously."""
189
+ if ignore_warnings:
190
+ warnings.simplefilter("ignore")
191
+ else:
192
+ warnings.simplefilter("default")
193
+
194
+ endpoint = f"/actor/{actor_id}/emissions"
195
+ url = f"{self.server}{endpoint}"
196
+ headers = {
197
+ "Accept": "application/json",
198
+ "User-Agent": "python-httpx/1.0",
199
+ }
200
+
201
+ async with httpx.AsyncClient() as client:
202
+ response = await client.get(url, headers=headers)
203
+ response.raise_for_status()
204
+ return response.json()
ledgerdata/base.py ADDED
@@ -0,0 +1,23 @@
1
+ from enum import Enum
2
+
3
+ from pydantic import HttpUrl
4
+ from pydantic.dataclasses import dataclass
5
+
6
+
7
+ class Env(str, Enum):
8
+ dev = "dev"
9
+ prod = "prod"
10
+
11
+
12
+ @dataclass
13
+ class Base:
14
+ version: str = "/api/v0"
15
+ env: Env = Env.prod
16
+
17
+ def __post_init__(self):
18
+ urls = {
19
+ Env.dev: "http://127.0.0.1:8000",
20
+ Env.prod: "https://orca-app-5ivtt.ondigitalocean.app",
21
+ }
22
+ self.base_url: HttpUrl = urls[self.env]
23
+ self.server = f"{self.base_url}{self.version}"
ledgerdata/client.py ADDED
@@ -0,0 +1,225 @@
1
+ import asyncio
2
+ from dataclasses import dataclass
3
+
4
+ import pandas as pd
5
+
6
+ from .actors import Actors
7
+ from .base import Base
8
+ from .datasource import Datasource
9
+ from .gwp import GWP
10
+ from .initiatives import Initiatives
11
+ from .sector import Sector
12
+
13
+
14
+ @dataclass
15
+ class Client(Base):
16
+ """ledgerdata client class
17
+
18
+ a high-level class to interact with the ledger database
19
+
20
+ Attributes:
21
+ version: str = API version (default "/api/v0)
22
+ env: str = "prod" for production server or "dev" for local development (default "prod")
23
+ """
24
+
25
+ # Limit concurrency to 10 requests at once, adjust as needed
26
+ _sem = asyncio.Semaphore(10)
27
+
28
+ def get_all_actors(
29
+ self,
30
+ ) -> pd.DataFrame:
31
+ """retreive all actors
32
+
33
+ this method is used to retriece a dataframe of all actors and their codes
34
+
35
+ Returns:
36
+ DataFrame: data of all actors
37
+ """
38
+ return pd.DataFrame(Actors(env=self.env, version=self.version).get_all_actors())
39
+
40
+ def parts_of_actor(
41
+ self, actor_id: str, part_type: str | None = None, *args, **kwargs
42
+ ) -> pd.DataFrame:
43
+ """retreive actor parts
44
+
45
+ returns subnational, cities, companies, etc. within an actor_id
46
+
47
+ Args:
48
+ actor_id (str|List[str]): code for actor your want to retrieve
49
+ part_type (str): retrieve actors from administrative part ['planet', 'country', 'adm1', 'adm2', 'city', 'organization', 'site']
50
+
51
+ Returns:
52
+ DataFrame: dataframe of actors parts
53
+ """
54
+ return pd.DataFrame(
55
+ Actors(env=self.env, version=self.version).parts_of_actor(
56
+ actor_id=actor_id, type=part_type
57
+ )
58
+ )
59
+
60
+ def gwp(
61
+ self,
62
+ assessment_report=None,
63
+ ) -> pd.DataFrame:
64
+ """retreive global warming potentials
65
+
66
+ Args:
67
+ actor_id (str|List[str]): code for actor your want to retrieve
68
+
69
+ Returns:
70
+ DataFrame: data for GWPs
71
+ """
72
+ return pd.DataFrame(
73
+ GWP(env=self.env, version=self.version).gwp(
74
+ assessment_report=assessment_report
75
+ )
76
+ )
77
+
78
+ def datasource(
79
+ self,
80
+ datasource_id=None,
81
+ ) -> pd.DataFrame:
82
+ """retrieve data sources
83
+
84
+ Args:
85
+ datasource_id (str|List[str]): code for datasource
86
+
87
+ Returns:
88
+ DataFrame: data for datasources
89
+ """
90
+ return pd.DataFrame(
91
+ Datasource(env=self.env, version=self.version).datasource(
92
+ datasource_id=datasource_id
93
+ )
94
+ )
95
+
96
+ def sector(self) -> pd.DataFrame:
97
+ """retrieve sectors
98
+
99
+ Returns:
100
+ DataFrame: data for sectors
101
+ """
102
+ return pd.DataFrame(Sector(env=self.env, version=self.version).sector())
103
+
104
+ def emissions(
105
+ self,
106
+ actor_id: str,
107
+ ) -> pd.DataFrame:
108
+ """retreive actor emissions
109
+
110
+ Args:
111
+ actor_id (str|List[str]): code for actor your want to retrieve
112
+
113
+ Returns:
114
+ DataFrame: data for each emissions dataset
115
+ """
116
+ return pd.DataFrame(
117
+ Actors(env=self.env, version=self.version).emissions(actor_id=actor_id)
118
+ )
119
+
120
+
121
+ def emissions_total_sector(
122
+ self,
123
+ actor_id: str,
124
+ ) -> pd.DataFrame:
125
+ """retreive actor emissions by sector
126
+
127
+ Args:
128
+ actor_id (str|List[str]): code for actor your want to retrieve
129
+
130
+ Returns:
131
+ DataFrame: data for each emissions dataset
132
+ """
133
+ return pd.DataFrame(
134
+ Actors(env=self.env, version=self.version).emissions_total_sector(actor_id=actor_id)
135
+ )
136
+
137
+ def emissions_raw(
138
+ self,
139
+ actor_id: str,
140
+ ) -> pd.DataFrame:
141
+ """retreive actor emissions raw
142
+
143
+ Args:
144
+ actor_id (str|List[str]): code for actor your want to retrieve
145
+
146
+ Returns:
147
+ DataFrame: data for each emissions dataset
148
+ """
149
+ return Actors(env=self.env, version=self.version).emissions(actor_id=actor_id)
150
+
151
+ def targets(self, actor_id: str) -> pd.DataFrame:
152
+ """retreive actor targets
153
+
154
+ Args:
155
+ actor_id (str|List[str]): code for actor your want to retrieve
156
+
157
+ Returns:
158
+ DataFrame: dataframe of targets
159
+ """
160
+ return pd.DataFrame(
161
+ Actors(env=self.env, version=self.version).targets(actor_id=actor_id)
162
+ )
163
+
164
+
165
+ def initiatives(self, initiative: str) -> pd.DataFrame:
166
+ """retrieve initiatives
167
+
168
+ Args:
169
+ initiative (str|List[str]): initiative namme
170
+
171
+ Returns:
172
+ DataFrame: dataframe of initiatives
173
+ """
174
+ return pd.DataFrame(
175
+ Initiatives(env=self.env, version=self.version).initiatives(initiative=initiative)
176
+ )
177
+
178
+ def population(self, actor_id: str) -> pd.DataFrame:
179
+ """retreive actor population
180
+
181
+ Args:
182
+ actor_id (str|List[str]): code for actor your want to retrieve
183
+ ignore_warnings (bool): ignore warning messages
184
+
185
+ Returns:
186
+ DataFrame: dataframe of population
187
+ """
188
+ return pd.DataFrame(
189
+ Actors(env=self.env, version=self.version).population(actor_id=actor_id)
190
+ )
191
+
192
+ def gdp(self, actor_id: str) -> pd.DataFrame:
193
+ """retreive actor gdp
194
+
195
+ Args:
196
+ actor_id (str|List[str]): code for actor your want to retrieve
197
+ ignore_warnings (bool): ignore warning messages
198
+
199
+ Returns:
200
+ DataFrame: dataframe of gdp
201
+ """
202
+ return pd.DataFrame(
203
+ Actors(env=self.env, version=self.version).gdp(actor_id=actor_id)
204
+ )
205
+
206
+ async def emissions_async(self, actor_id: str) -> pd.DataFrame:
207
+ data = await Actors(env=self.env, version=self.version).emissions_async(
208
+ actor_id=actor_id
209
+ )
210
+ return pd.DataFrame(data)
211
+
212
+ async def _emissions_with_sem(self, actor_id: str) -> pd.DataFrame:
213
+ async with self._sem:
214
+ return await self.emissions_async(actor_id)
215
+
216
+ async def emissions_many(self, actor_ids: list[str]) -> list[pd.DataFrame]:
217
+ tasks = [self._emissions_with_sem(actor_id) for actor_id in actor_ids]
218
+ return await asyncio.gather(*tasks)
219
+
220
+ # sync wrappers that run the async code in an event loop
221
+ def emissions_sync(self, actor_id: str) -> pd.DataFrame:
222
+ return asyncio.run(self.emissions_async(actor_id))
223
+
224
+ def emissions_many_sync(self, actor_ids: list[str]) -> list[pd.DataFrame]:
225
+ return asyncio.run(self.emissions_many(actor_ids))
@@ -0,0 +1,37 @@
1
+ import requests
2
+ from pydantic.dataclasses import dataclass
3
+
4
+ from .base import Base
5
+
6
+
7
+ @dataclass
8
+ class Datasource(Base):
9
+ """retrieve emissions
10
+
11
+ Returns:
12
+ object
13
+ """
14
+
15
+ def datasource(self, datasource_id=None, *args, **kwargs):
16
+ """retrieve actor emissions
17
+
18
+ Args:
19
+ datasource_id (str): code for datasource
20
+
21
+ Returns:
22
+ DataFrame:
23
+ """
24
+ endpoint = "/datasource/"
25
+ url = f"{self.server}{endpoint}"
26
+ headers = {
27
+ "Accept": "application/json",
28
+ "User-Agent": "python-httpx/1.0",
29
+ }
30
+
31
+ # Add query parameters
32
+ params = {}
33
+ if datasource_id:
34
+ params["datasource_id"] = datasource_id
35
+
36
+ response = requests.get(url, headers=headers, params=params).json()
37
+ return response
@@ -0,0 +1,64 @@
1
+ import warnings
2
+
3
+ import httpx
4
+ import requests
5
+ from pydantic.dataclasses import dataclass
6
+
7
+ from .base import Base
8
+
9
+
10
+ @dataclass
11
+ class Emissions(Base):
12
+ """retrieve emissions
13
+
14
+ Returns:
15
+ object
16
+ """
17
+
18
+ def emissions(self, actor_id: str, ignore_warnings: bool = False, *args, **kwargs):
19
+ """retreive actor emissions
20
+
21
+ Args:
22
+ actor_id (str): code for actor your want to retrieve
23
+ ignore_warnings (bool): ignore warning messages
24
+
25
+ Returns:
26
+ DataFrame: data for each emissions dataset
27
+ """
28
+ (
29
+ warnings.simplefilter("ignore")
30
+ if ignore_warnings
31
+ else warnings.simplefilter("default")
32
+ )
33
+ endpoint = f"/actor/{actor_id}/emissions"
34
+ url = f"{self.server}{endpoint}"
35
+ headers = {
36
+ "Accept": "application/json",
37
+ "User-Agent": "python-httpx/1.0",
38
+ }
39
+
40
+ response = requests.get(url, headers=headers).json()
41
+ # data_list = response.get("data", None)
42
+ # df = pd.DataFrame(response).sort_values(by=["year"])
43
+ return response
44
+
45
+ async def emissions_async(
46
+ self, actor_id: str, ignore_warnings: bool = False, *args, **kwargs
47
+ ):
48
+ """Retrieve actor emissions asynchronously."""
49
+ if ignore_warnings:
50
+ warnings.simplefilter("ignore")
51
+ else:
52
+ warnings.simplefilter("default")
53
+
54
+ endpoint = f"/actor/{actor_id}/emissions"
55
+ url = f"{self.server}{endpoint}"
56
+ headers = {
57
+ "Accept": "application/json",
58
+ "User-Agent": "python-httpx/1.0",
59
+ }
60
+
61
+ async with httpx.AsyncClient() as client:
62
+ response = await client.get(url, headers=headers)
63
+ response.raise_for_status()
64
+ return response.json()
ledgerdata/gdp.py ADDED
@@ -0,0 +1,36 @@
1
+ import warnings
2
+ from typing import ClassVar
3
+
4
+ import pandas as pd
5
+ import requests
6
+ from pydantic.dataclasses import dataclass
7
+
8
+ from .base import Base
9
+
10
+
11
+ @dataclass
12
+ class ActorData(Base):
13
+ endpoint: ClassVar[str]
14
+
15
+ def fetch(
16
+ self,
17
+ actor_id: str,
18
+ ignore_warnings: bool = False,
19
+ *args,
20
+ **kwargs,
21
+ ):
22
+ """Retrieve actor data for the given endpoint."""
23
+ if ignore_warnings:
24
+ warnings.simplefilter("ignore")
25
+ else:
26
+ warnings.simplefilter("default")
27
+
28
+ url = f"{self.server}{self.endpoint}/{actor_id}"
29
+ headers = {"Accept": "application/json"}
30
+ response = requests.get(url, headers=headers).json()
31
+ return pd.DataFrame(response)
32
+
33
+
34
+ @dataclass
35
+ class GDP(ActorData):
36
+ endpoint: ClassVar[str] = "/gdp"
ledgerdata/gwp.py ADDED
@@ -0,0 +1,38 @@
1
+ import requests
2
+ from pydantic.dataclasses import dataclass
3
+
4
+ from .base import Base
5
+
6
+
7
+ @dataclass
8
+ class GWP(Base):
9
+ """retrieve emissions
10
+
11
+ Returns:
12
+ object
13
+ """
14
+
15
+ def gwp(self, assessment_report=None, *args, **kwargs):
16
+ """retreive actor emissions
17
+
18
+ Args:
19
+ actor_id (str): code for actor your want to retrieve
20
+ ignore_warnings (bool): ignore warning messages
21
+
22
+ Returns:
23
+ DataFrame: data for each emissions dataset
24
+ """
25
+ endpoint = "/gwp/"
26
+ url = f"{self.server}{endpoint}"
27
+ headers = {
28
+ "Accept": "application/json",
29
+ "User-Agent": "python-httpx/1.0",
30
+ }
31
+
32
+ # Add query parameters
33
+ params = {}
34
+ if assessment_report:
35
+ params["assessment_report"] = assessment_report
36
+
37
+ response = requests.get(url, headers=headers, params=params).json()
38
+ return response
@@ -0,0 +1,37 @@
1
+ import requests
2
+ from pydantic.dataclasses import dataclass
3
+
4
+ from .base import Base
5
+
6
+
7
+ @dataclass
8
+ class Initiatives(Base):
9
+ """retrieve emissions
10
+
11
+ Returns:
12
+ object
13
+ """
14
+
15
+ def initiatives(self, initiative="us_climate_alliance", *args, **kwargs):
16
+ """retreive actors part of an initiative
17
+
18
+ Args:
19
+ initiative (str): InitiativeType
20
+
21
+ Returns:
22
+ DataFrame: data for selected initiative
23
+ """
24
+ endpoint = "/initiatives/"
25
+ url = f"{self.server}{endpoint}"
26
+ headers = {
27
+ "Accept": "application/json",
28
+ "User-Agent": "python-httpx/1.0",
29
+ }
30
+
31
+ # Add query parameters
32
+ params = {}
33
+ if initiative:
34
+ params["initiative"] = initiative
35
+
36
+ response = requests.get(url, headers=headers, params=params).json()
37
+ return response
@@ -0,0 +1,37 @@
1
+ import warnings
2
+
3
+ import requests
4
+ from pydantic.dataclasses import dataclass
5
+
6
+ from .base import Base
7
+
8
+
9
+ @dataclass
10
+ class Population(Base):
11
+ """ActorOveriew API class
12
+ get overview information of an actor
13
+
14
+ Returns:
15
+ object
16
+ """
17
+
18
+ def population(self, actor_id: str, ignore_warnings: bool = False, *args, **kwargs):
19
+ """retrieve population data
20
+
21
+ Args:
22
+ actor_id (str): code for actor your want to retrieve
23
+ ignore_warnings (bool): ignore warning messages
24
+
25
+ Returns:
26
+ DataFrame: data for each emissions dataset
27
+ """
28
+ (
29
+ warnings.simplefilter("ignore")
30
+ if ignore_warnings
31
+ else warnings.simplefilter("default")
32
+ )
33
+ endpoint = f"/population/{actor_id}"
34
+ url = f"{self.server}{endpoint}"
35
+ headers = {"Accept": "application/json"}
36
+ response = requests.get(url, headers=headers).json()
37
+ return response
ledgerdata/sector.py ADDED
@@ -0,0 +1,34 @@
1
+ import requests
2
+ from pydantic.dataclasses import dataclass
3
+
4
+ from .base import Base
5
+
6
+
7
+ @dataclass
8
+ class Sector(Base):
9
+ """retrieve sectors
10
+
11
+ Returns:
12
+ object
13
+ """
14
+
15
+ def sector(self, *args, **kwargs):
16
+ """retrieve sectors
17
+
18
+ Returns:
19
+ DataFrame:
20
+ """
21
+ endpoint = "/sector/"
22
+ url = f"{self.server}{endpoint}"
23
+ headers = {
24
+ "Accept": "application/json",
25
+ "User-Agent": "python-httpx/1.0",
26
+ }
27
+
28
+ # Add query parameters
29
+ params = {}
30
+ # if datasource_id:
31
+ # params["datasource_id"] = datasource_id
32
+
33
+ response = requests.get(url, headers=headers, params=params).json()
34
+ return response
ledgerdata/targets.py ADDED
@@ -0,0 +1,36 @@
1
+ import warnings
2
+
3
+ import requests
4
+ from pydantic.dataclasses import dataclass
5
+
6
+ from .base import Base
7
+
8
+
9
+ @dataclass
10
+ class Targets(Base):
11
+ """retrieve emission targets
12
+
13
+ Returns:
14
+ object
15
+ """
16
+
17
+ def targets(self, actor_id: str, ignore_warnings: bool = False, *args, **kwargs):
18
+ """retreive actor emissions
19
+
20
+ Args:
21
+ actor_id (str): code for actor your want to retrieve
22
+ ignore_warnings (bool): ignore warning messages
23
+
24
+ Returns:
25
+ DataFrame: data for each emissions dataset
26
+ """
27
+ (
28
+ warnings.simplefilter("ignore")
29
+ if ignore_warnings
30
+ else warnings.simplefilter("default")
31
+ )
32
+ endpoint = f"/targets/{actor_id}"
33
+ url = f"{self.server}{endpoint}"
34
+ headers = {"Accept": "application/json"}
35
+ response = requests.get(url, headers=headers).json()
36
+ return response
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.5
2
+ Name: ledgerdata
3
+ Version: 0.1.0.dev6
4
+ Summary: Python client for LEDGER database
5
+ Author-email: Luke Gloege <lucas.gloege@yale.edu>
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: httpx>=0.28.1
9
+ Requires-Dist: pandas>=3.0.6
10
+ Requires-Dist: psycopg>=3.3.6
11
+ Requires-Dist: pydantic>=2.14.1
12
+ Requires-Dist: requests>=2.34.2
13
+ Requires-Dist: ruff>=0.17.2
14
+ Description-Content-Type: text/markdown
15
+
16
+ # ledgerdata: The LEDGER Python Client
17
+
18
+ This Repo contains the LEDGER Python Client
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ uv add git+https://github.com/LEDGER-project/ledgerdata.git@main
24
+ ```
25
+
26
+ or with pip
27
+
28
+ ```bash
29
+ pip install git+https://github.com/LEDGER-project/ledgerdata.git@main
30
+ ```
31
+
32
+ ## Documentation
33
+
34
+ The official documentation for the entire LEDGER project is available at: [https://ledger-project.github.io/](https://ledger-project.github.io/)
@@ -0,0 +1,17 @@
1
+ ledgerdata/__init__.py,sha256=kQkuE0d_JWQxmbZUPRLUeB2Y0QSg045ejs3WMI8oKpU,438
2
+ ledgerdata/actors.py,sha256=fJLKa40Hu9OSS8yDmH9BYaejv9nYBejjJp6dwFwSNj0,7600
3
+ ledgerdata/base.py,sha256=yzbVcouYXPDcyf5SqhbXIZ7CigE-tjMGWjX9hoUuspM,504
4
+ ledgerdata/client.py,sha256=4vhnSyo5T0fHnijlm4FAs5tibnDAiCsQJ4XGygBfjrs,6577
5
+ ledgerdata/datasource.py,sha256=n-0qQILAXxjDBS2ckdY67uoqnk142ozvfg4EpPYALG8,828
6
+ ledgerdata/emissions.py,sha256=6P_vuMpNsF0EhL5qKhlDSUwnmNM0zu65FQHXSwuaeCg,1813
7
+ ledgerdata/gdp.py,sha256=O0u03vvF8Y7aoivHdQF9obngbrkXikYYXxVRz4depKQ,811
8
+ ledgerdata/gwp.py,sha256=YhjvlO5kPynt5IsD5qyg2r16LcnOufihWI1gOWbOX4Y,927
9
+ ledgerdata/initiatives.py,sha256=L1UfrQAPtts95-GA3llFf7sU46c3UfyYEuwwdd2uYBU,871
10
+ ledgerdata/population.py,sha256=Plo-IfvrnAmwTUjAGhztprvWcPU8sj50bX0wpKGb9Xc,961
11
+ ledgerdata/sector.py,sha256=KKF0SsgMgP5OH1C_OyLD2CBQ9yax3SkQQyahsx1wp4A,721
12
+ ledgerdata/targets.py,sha256=P9fMl4C9lAN0GtkvUBL20AnMWgw4qKMTGQ4UvkaqKT8,914
13
+ ledgerdata-0.1.0.dev6.dist-info/METADATA,sha256=3OvPuUAqpgV60qfajpc4aUmJN_Looaed_VKjsAkewTE,858
14
+ ledgerdata-0.1.0.dev6.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
15
+ ledgerdata-0.1.0.dev6.dist-info/entry_points.txt,sha256=-jmCqcPPOqamUodczh91vTv1zMG_kQyDUOQmt3eO5MI,47
16
+ ledgerdata-0.1.0.dev6.dist-info/licenses/LICENSE,sha256=vFovm9NfuoM4HokZBt6sYh7tTXwUSRNCYp_ugpqGzk0,1071
17
+ ledgerdata-0.1.0.dev6.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ledgerdata = ledgerdata:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LEDGER-project
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.