jiskta 0.5.0__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.
jiskta-0.5.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jiskta
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.
jiskta-0.5.0/PKG-INFO ADDED
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: jiskta
3
+ Version: 0.5.0
4
+ Summary: Python SDK for the Jiskta Climate Data API
5
+ License: MIT
6
+ Project-URL: Homepage, https://jiskta.com
7
+ Project-URL: Documentation, https://jiskta.com/docs
8
+ Project-URL: Repository, https://github.com/jiskta/jiskta-python
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: requests>=2.28
18
+ Provides-Extra: pandas
19
+ Requires-Dist: pandas>=1.5; extra == "pandas"
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest; extra == "dev"
22
+ Requires-Dist: responses; extra == "dev"
23
+ Requires-Dist: pandas; extra == "dev"
24
+ Dynamic: license-file
25
+
26
+ # jiskta-python
27
+
28
+ Python SDK for the [Jiskta Climate Data API](https://jiskta.com) — query historical air quality data (NO₂, PM2.5, PM10, O₃) and ERA5 meteorological data via a simple Python interface.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install git+https://github.com/jiskta/jiskta-python.git
34
+ ```
35
+
36
+ Pandas is optional but recommended:
37
+ ```bash
38
+ pip install "git+https://github.com/jiskta/jiskta-python.git#egg=jiskta[pandas]"
39
+ ```
40
+
41
+ ## Quick start
42
+
43
+ ```python
44
+ from jiskta import JisktaClient
45
+
46
+ client = JisktaClient(api_key="sk_live_...")
47
+
48
+ # Daily NO₂ and PM2.5 over Paris in 2023
49
+ df = client.query(
50
+ lat=(48.7, 49.0),
51
+ lon=(2.2, 2.5),
52
+ start="2023-01",
53
+ end="2023-12",
54
+ variables=["no2", "pm2p5"],
55
+ aggregate="daily",
56
+ )
57
+ print(df.head())
58
+ # lat lon date no2_mean pm2p5_mean
59
+ # 0 48.7500 2.250 2023-01-01 12.34 8.21
60
+ # ...
61
+ ```
62
+
63
+ ## All parameters
64
+
65
+ ```python
66
+ df = client.query(
67
+ lat=(lat_min, lat_max), # bounding box
68
+ lon=(lon_min, lon_max),
69
+ start="YYYY-MM-DD", # or "YYYY-MM"
70
+ end="YYYY-MM-DD",
71
+ variables=["no2"], # no2 | pm2p5 | pm10 | o3
72
+ aggregate="daily", # hourly | daily | monthly | annual
73
+ # area_hourly | area_daily | area_monthly
74
+ # diurnal | exceedance | percentile
75
+ threshold=40.0, # µg/m³ (exceedance mode)
76
+ percentile=95, # 0-100 (percentile mode)
77
+ )
78
+ ```
79
+
80
+ ## Summary statistics (no DataFrame)
81
+
82
+ ```python
83
+ result = client.stats(
84
+ lat=(48.7, 49.0),
85
+ lon=(2.2, 2.5),
86
+ start="2023-01",
87
+ end="2023-01",
88
+ variables=["no2"],
89
+ )
90
+ print(result["output"])
91
+ ```
92
+
93
+ ## Error handling
94
+
95
+ ```python
96
+ from jiskta import JisktaClient, AuthError, InsufficientCreditsError, RateLimitError, JisktaError
97
+
98
+ try:
99
+ df = client.query(...)
100
+ except AuthError:
101
+ print("Invalid API key")
102
+ except InsufficientCreditsError:
103
+ print("Buy more credits at https://jiskta.com/pricing")
104
+ except RateLimitError:
105
+ print("Server busy, retry later")
106
+ except JisktaError as e:
107
+ print(f"API error {e.status_code}: {e}")
108
+ ```
109
+
110
+ ## Named area queries
111
+
112
+ Skip lat/lon by passing a named region:
113
+
114
+ ```python
115
+ df = client.query(
116
+ area="paris",
117
+ start="2023-01",
118
+ end="2023-12",
119
+ variables=["no2"],
120
+ aggregate="daily",
121
+ )
122
+
123
+ result = client.stats(area="belgium", start="2023-01", end="2023-12")
124
+ ```
125
+
126
+ Supported names depend on the API (e.g. `"paris"`, `"france"`, `"belgium"`).
127
+
128
+ ## New aggregates
129
+
130
+ ```python
131
+ # Statistical aggregates
132
+ df = client.query(..., aggregate="max") # daily/monthly max
133
+ df = client.query(..., aggregate="min") # daily/monthly min
134
+ df = client.query(..., aggregate="stddev") # standard deviation
135
+ df = client.query(..., aggregate="cumulative") # running total (e.g. precipitation)
136
+
137
+ # Analytical aggregates
138
+ df = client.query(..., aggregate="seasonal") # DJF/MAM/JJA/SON means
139
+ df = client.query(..., aggregate="trend") # linear trend per grid cell
140
+ ```
141
+
142
+ ## Wind variables
143
+
144
+ `wind_speed` and `wind_dir` are derived ERA5 variables (computed from `u10`/`v10`):
145
+
146
+ ```python
147
+ df = client.query(
148
+ lat=(48.7, 49.0), lon=(2.2, 2.5),
149
+ start="2023-01", end="2023-12",
150
+ variables=["wind_speed", "wind_dir"],
151
+ aggregate="daily",
152
+ )
153
+ ```
154
+
155
+ ## Polygon-masked queries
156
+
157
+ Pass any GeoJSON `Polygon` or `MultiPolygon` geometry to restrict results to cells
158
+ whose centres fall inside the polygon:
159
+
160
+ ```python
161
+ mask = {
162
+ "type": "Polygon",
163
+ "coordinates": [[[2.2, 48.7], [2.5, 48.7], [2.5, 49.0], [2.2, 49.0], [2.2, 48.7]]],
164
+ }
165
+
166
+ df = client.query_with_mask(
167
+ lat_min=48.7, lat_max=49.0,
168
+ lon_min=2.2, lon_max=2.5,
169
+ start="2023-01",
170
+ end="2023-12",
171
+ variables=["no2"],
172
+ aggregate="daily",
173
+ mask=mask,
174
+ )
175
+ ```
176
+
177
+ ## Advanced options
178
+
179
+ ```python
180
+ df = client.query(
181
+ lat=(48.7, 49.0), lon=(2.2, 2.5),
182
+ start="2023-01", end="2023-12",
183
+ variables=["no2"],
184
+ sort_by="no2_mean", # sort CSV output by column
185
+ sort_dir="desc", # "asc" or "desc"
186
+ unit="ppb", # convert output units
187
+ round=2, # decimal places
188
+ dry_run=True, # cost estimate only — no query executed
189
+ missing_null=True, # empty string for missing cells
190
+ include_polygon=True, # include area_polygon GeoJSON in raw response
191
+ )
192
+ ```
193
+
194
+ ## License
195
+
196
+ MIT
jiskta-0.5.0/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # jiskta-python
2
+
3
+ Python SDK for the [Jiskta Climate Data API](https://jiskta.com) — query historical air quality data (NO₂, PM2.5, PM10, O₃) and ERA5 meteorological data via a simple Python interface.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install git+https://github.com/jiskta/jiskta-python.git
9
+ ```
10
+
11
+ Pandas is optional but recommended:
12
+ ```bash
13
+ pip install "git+https://github.com/jiskta/jiskta-python.git#egg=jiskta[pandas]"
14
+ ```
15
+
16
+ ## Quick start
17
+
18
+ ```python
19
+ from jiskta import JisktaClient
20
+
21
+ client = JisktaClient(api_key="sk_live_...")
22
+
23
+ # Daily NO₂ and PM2.5 over Paris in 2023
24
+ df = client.query(
25
+ lat=(48.7, 49.0),
26
+ lon=(2.2, 2.5),
27
+ start="2023-01",
28
+ end="2023-12",
29
+ variables=["no2", "pm2p5"],
30
+ aggregate="daily",
31
+ )
32
+ print(df.head())
33
+ # lat lon date no2_mean pm2p5_mean
34
+ # 0 48.7500 2.250 2023-01-01 12.34 8.21
35
+ # ...
36
+ ```
37
+
38
+ ## All parameters
39
+
40
+ ```python
41
+ df = client.query(
42
+ lat=(lat_min, lat_max), # bounding box
43
+ lon=(lon_min, lon_max),
44
+ start="YYYY-MM-DD", # or "YYYY-MM"
45
+ end="YYYY-MM-DD",
46
+ variables=["no2"], # no2 | pm2p5 | pm10 | o3
47
+ aggregate="daily", # hourly | daily | monthly | annual
48
+ # area_hourly | area_daily | area_monthly
49
+ # diurnal | exceedance | percentile
50
+ threshold=40.0, # µg/m³ (exceedance mode)
51
+ percentile=95, # 0-100 (percentile mode)
52
+ )
53
+ ```
54
+
55
+ ## Summary statistics (no DataFrame)
56
+
57
+ ```python
58
+ result = client.stats(
59
+ lat=(48.7, 49.0),
60
+ lon=(2.2, 2.5),
61
+ start="2023-01",
62
+ end="2023-01",
63
+ variables=["no2"],
64
+ )
65
+ print(result["output"])
66
+ ```
67
+
68
+ ## Error handling
69
+
70
+ ```python
71
+ from jiskta import JisktaClient, AuthError, InsufficientCreditsError, RateLimitError, JisktaError
72
+
73
+ try:
74
+ df = client.query(...)
75
+ except AuthError:
76
+ print("Invalid API key")
77
+ except InsufficientCreditsError:
78
+ print("Buy more credits at https://jiskta.com/pricing")
79
+ except RateLimitError:
80
+ print("Server busy, retry later")
81
+ except JisktaError as e:
82
+ print(f"API error {e.status_code}: {e}")
83
+ ```
84
+
85
+ ## Named area queries
86
+
87
+ Skip lat/lon by passing a named region:
88
+
89
+ ```python
90
+ df = client.query(
91
+ area="paris",
92
+ start="2023-01",
93
+ end="2023-12",
94
+ variables=["no2"],
95
+ aggregate="daily",
96
+ )
97
+
98
+ result = client.stats(area="belgium", start="2023-01", end="2023-12")
99
+ ```
100
+
101
+ Supported names depend on the API (e.g. `"paris"`, `"france"`, `"belgium"`).
102
+
103
+ ## New aggregates
104
+
105
+ ```python
106
+ # Statistical aggregates
107
+ df = client.query(..., aggregate="max") # daily/monthly max
108
+ df = client.query(..., aggregate="min") # daily/monthly min
109
+ df = client.query(..., aggregate="stddev") # standard deviation
110
+ df = client.query(..., aggregate="cumulative") # running total (e.g. precipitation)
111
+
112
+ # Analytical aggregates
113
+ df = client.query(..., aggregate="seasonal") # DJF/MAM/JJA/SON means
114
+ df = client.query(..., aggregate="trend") # linear trend per grid cell
115
+ ```
116
+
117
+ ## Wind variables
118
+
119
+ `wind_speed` and `wind_dir` are derived ERA5 variables (computed from `u10`/`v10`):
120
+
121
+ ```python
122
+ df = client.query(
123
+ lat=(48.7, 49.0), lon=(2.2, 2.5),
124
+ start="2023-01", end="2023-12",
125
+ variables=["wind_speed", "wind_dir"],
126
+ aggregate="daily",
127
+ )
128
+ ```
129
+
130
+ ## Polygon-masked queries
131
+
132
+ Pass any GeoJSON `Polygon` or `MultiPolygon` geometry to restrict results to cells
133
+ whose centres fall inside the polygon:
134
+
135
+ ```python
136
+ mask = {
137
+ "type": "Polygon",
138
+ "coordinates": [[[2.2, 48.7], [2.5, 48.7], [2.5, 49.0], [2.2, 49.0], [2.2, 48.7]]],
139
+ }
140
+
141
+ df = client.query_with_mask(
142
+ lat_min=48.7, lat_max=49.0,
143
+ lon_min=2.2, lon_max=2.5,
144
+ start="2023-01",
145
+ end="2023-12",
146
+ variables=["no2"],
147
+ aggregate="daily",
148
+ mask=mask,
149
+ )
150
+ ```
151
+
152
+ ## Advanced options
153
+
154
+ ```python
155
+ df = client.query(
156
+ lat=(48.7, 49.0), lon=(2.2, 2.5),
157
+ start="2023-01", end="2023-12",
158
+ variables=["no2"],
159
+ sort_by="no2_mean", # sort CSV output by column
160
+ sort_dir="desc", # "asc" or "desc"
161
+ unit="ppb", # convert output units
162
+ round=2, # decimal places
163
+ dry_run=True, # cost estimate only — no query executed
164
+ missing_null=True, # empty string for missing cells
165
+ include_polygon=True, # include area_polygon GeoJSON in raw response
166
+ )
167
+ ```
168
+
169
+ ## License
170
+
171
+ MIT
@@ -0,0 +1,31 @@
1
+ """
2
+ Jiskta Python SDK
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ Simple client for the Jiskta Climate Data API.
6
+ https://jiskta.com/docs
7
+
8
+ Usage::
9
+
10
+ from jiskta import JisktaClient
11
+
12
+ client = JisktaClient(api_key="sk_live_...")
13
+ df = client.query(
14
+ lat=(48.0, 49.0),
15
+ lon=(2.0, 3.0),
16
+ start="2023-01",
17
+ end="2023-12",
18
+ variables=["no2", "pm2p5"],
19
+ )
20
+ print(df.head())
21
+ """
22
+
23
+ from .client import JisktaClient, Variable, CamsVariable, Era5Variable, Aggregate
24
+ from .exceptions import JisktaError, AuthError, InsufficientCreditsError, RateLimitError
25
+
26
+ __version__ = "0.5.0"
27
+ __all__ = [
28
+ "JisktaClient",
29
+ "Variable", "CamsVariable", "Era5Variable", "Aggregate",
30
+ "JisktaError", "AuthError", "InsufficientCreditsError", "RateLimitError",
31
+ ]