pyopensky 2.4__tar.gz → 2.6__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.
- {pyopensky-2.4 → pyopensky-2.6}/PKG-INFO +11 -15
- {pyopensky-2.4 → pyopensky-2.6}/pyproject.toml +2 -1
- {pyopensky-2.4 → pyopensky-2.6}/readme.md +8 -15
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/schema.py +94 -50
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/trino.py +116 -17
- {pyopensky-2.4 → pyopensky-2.6}/license.txt +0 -0
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/__init__.py +0 -0
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/api.py +0 -0
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/config.py +0 -0
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/impala.py +0 -0
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/py.typed +0 -0
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/rest.py +0 -0
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/s3.py +0 -0
- {pyopensky-2.4 → pyopensky-2.6}/src/pyopensky/time.py +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyopensky
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6
|
|
4
4
|
Summary: A Python interface for OpenSky database
|
|
5
|
+
Home-page: https://github.com/open-aviation/pyopensky/
|
|
5
6
|
License: MIT
|
|
6
7
|
Author: Xavier Olive
|
|
7
8
|
Author-email: git@xoolive.org
|
|
@@ -21,13 +22,14 @@ Requires-Dist: pyjwt (>=2.7.0)
|
|
|
21
22
|
Requires-Dist: tqdm (>=4.65.0)
|
|
22
23
|
Requires-Dist: trino[sqlalchemy] (>=0.322)
|
|
23
24
|
Requires-Dist: typing-extensions (>=4.5.0)
|
|
25
|
+
Project-URL: Repository, https://github.com/open-aviation/pyopensky/
|
|
24
26
|
Description-Content-Type: text/markdown
|
|
25
27
|
|
|
26
28
|
# pyopensky
|
|
27
29
|
|
|
28
30
|
The `pyopensky` Python library provides functions to download data from the OpenSky Network live API and historical databases. It aims at making ADS-B and Mode S data from OpenSky easily accessible in the Python programming environment.
|
|
29
31
|
|
|
30
|
-
Full documentation on https://open-aviation.github.io/pyopensky
|
|
32
|
+
Full documentation on [https://open-aviation.github.io/pyopensky](https://open-aviation.github.io/pyopensky)
|
|
31
33
|
|
|
32
34
|
## Installation
|
|
33
35
|
|
|
@@ -55,13 +57,16 @@ See details in the [documentation](https://open-aviation.github.io/pyopensky/cre
|
|
|
55
57
|
|
|
56
58
|
## Usage
|
|
57
59
|
|
|
60
|
+
> [!IMPORTANT]
|
|
61
|
+
> The Impala shell is now deprecated. Please upgrade to Trino.
|
|
62
|
+
|
|
58
63
|
- from the [REST API](https://open-aviation.github.io/pyopensky/rest.html):
|
|
59
64
|
|
|
60
65
|
```python
|
|
61
66
|
from pyopensky.rest import REST
|
|
62
|
-
|
|
67
|
+
|
|
63
68
|
rest = REST()
|
|
64
|
-
|
|
69
|
+
|
|
65
70
|
rest.states()
|
|
66
71
|
rest.tracks(icao24)
|
|
67
72
|
rest.routes(callsign)
|
|
@@ -69,25 +74,16 @@ See details in the [documentation](https://open-aviation.github.io/pyopensky/cre
|
|
|
69
74
|
rest.arrival(airport, begin, end)
|
|
70
75
|
rest.departure(airport, begin, end)
|
|
71
76
|
```
|
|
72
|
-
- from the [Impala](https://open-aviation.github.io/pyopensky/impala.html) shell (requires authentication):
|
|
73
77
|
|
|
74
|
-
```python
|
|
75
|
-
from pyopensky.impala import Impala
|
|
76
|
-
|
|
77
|
-
impala = Impala()
|
|
78
|
-
# full description of the whole set of parameters in the documentation
|
|
79
|
-
impala.flightlist(start, stop, *, airport, callsign, icao24)
|
|
80
|
-
impala.history(start, stop, *, callsign, icao24, bounds)
|
|
81
|
-
impala.rawdata(start, stop, *, callsign, icao24, bounds)
|
|
82
|
-
```
|
|
83
78
|
- from the [Trino](https://open-aviation.github.io/pyopensky/trino.html) database (requires authentication):
|
|
84
79
|
|
|
85
80
|
```python
|
|
86
81
|
from pyopensky.trino import Trino
|
|
87
|
-
|
|
82
|
+
|
|
88
83
|
trino = Trino()
|
|
89
84
|
# full description of the whole set of parameters in the documentation
|
|
90
85
|
trino.flightlist(start, stop, *, airport, callsign, icao24)
|
|
91
86
|
trino.history(start, stop, *, callsign, icao24, bounds)
|
|
92
87
|
trino.rawdata(start, stop, *, callsign, icao24, bounds)
|
|
93
88
|
```
|
|
89
|
+
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pyopensky"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.6"
|
|
4
4
|
description = "A Python interface for OpenSky database"
|
|
5
|
+
repository = "https://github.com/open-aviation/pyopensky/"
|
|
5
6
|
authors = ["Xavier Olive <git@xoolive.org>", "Junzi Sun <j.sun-1@tudelft.nl>"]
|
|
6
7
|
license = "MIT"
|
|
7
8
|
readme = "readme.md"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `pyopensky` Python library provides functions to download data from the OpenSky Network live API and historical databases. It aims at making ADS-B and Mode S data from OpenSky easily accessible in the Python programming environment.
|
|
4
4
|
|
|
5
|
-
Full documentation on https://open-aviation.github.io/pyopensky
|
|
5
|
+
Full documentation on [https://open-aviation.github.io/pyopensky](https://open-aviation.github.io/pyopensky)
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -30,13 +30,16 @@ See details in the [documentation](https://open-aviation.github.io/pyopensky/cre
|
|
|
30
30
|
|
|
31
31
|
## Usage
|
|
32
32
|
|
|
33
|
+
> [!IMPORTANT]
|
|
34
|
+
> The Impala shell is now deprecated. Please upgrade to Trino.
|
|
35
|
+
|
|
33
36
|
- from the [REST API](https://open-aviation.github.io/pyopensky/rest.html):
|
|
34
37
|
|
|
35
38
|
```python
|
|
36
39
|
from pyopensky.rest import REST
|
|
37
|
-
|
|
40
|
+
|
|
38
41
|
rest = REST()
|
|
39
|
-
|
|
42
|
+
|
|
40
43
|
rest.states()
|
|
41
44
|
rest.tracks(icao24)
|
|
42
45
|
rest.routes(callsign)
|
|
@@ -44,25 +47,15 @@ See details in the [documentation](https://open-aviation.github.io/pyopensky/cre
|
|
|
44
47
|
rest.arrival(airport, begin, end)
|
|
45
48
|
rest.departure(airport, begin, end)
|
|
46
49
|
```
|
|
47
|
-
- from the [Impala](https://open-aviation.github.io/pyopensky/impala.html) shell (requires authentication):
|
|
48
50
|
|
|
49
|
-
```python
|
|
50
|
-
from pyopensky.impala import Impala
|
|
51
|
-
|
|
52
|
-
impala = Impala()
|
|
53
|
-
# full description of the whole set of parameters in the documentation
|
|
54
|
-
impala.flightlist(start, stop, *, airport, callsign, icao24)
|
|
55
|
-
impala.history(start, stop, *, callsign, icao24, bounds)
|
|
56
|
-
impala.rawdata(start, stop, *, callsign, icao24, bounds)
|
|
57
|
-
```
|
|
58
51
|
- from the [Trino](https://open-aviation.github.io/pyopensky/trino.html) database (requires authentication):
|
|
59
52
|
|
|
60
53
|
```python
|
|
61
54
|
from pyopensky.trino import Trino
|
|
62
|
-
|
|
55
|
+
|
|
63
56
|
trino = Trino()
|
|
64
57
|
# full description of the whole set of parameters in the documentation
|
|
65
58
|
trino.flightlist(start, stop, *, airport, callsign, icao24)
|
|
66
59
|
trino.history(start, stop, *, callsign, icao24, bounds)
|
|
67
60
|
trino.rawdata(start, stop, *, callsign, icao24, bounds)
|
|
68
|
-
```
|
|
61
|
+
```
|
|
@@ -67,6 +67,17 @@ class UTCTimestampFloat(TypeDecorator[pd.Timestamp]):
|
|
|
67
67
|
return super().process_bind_param(value, dialect)
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
class AddressString(TypeDecorator[str]):
|
|
71
|
+
"""Automatic coercing of icao24 addresses into low characters."""
|
|
72
|
+
|
|
73
|
+
impl = String
|
|
74
|
+
|
|
75
|
+
def process_bind_param(self, value: str | None, dialect: Dialect) -> Any:
|
|
76
|
+
if isinstance(value, str):
|
|
77
|
+
return value.lower()
|
|
78
|
+
return super().process_bind_param(value, dialect)
|
|
79
|
+
|
|
80
|
+
|
|
70
81
|
class CallsignString(TypeDecorator[str]):
|
|
71
82
|
"""Automatic coercing of callsigns into 8-char left padded strings.
|
|
72
83
|
|
|
@@ -122,7 +133,7 @@ class TrackRow:
|
|
|
122
133
|
|
|
123
134
|
@dataclass
|
|
124
135
|
class AirportCandidateRow:
|
|
125
|
-
icao24:
|
|
136
|
+
icao24: Address
|
|
126
137
|
horizdistance: int
|
|
127
138
|
vertdistance: int
|
|
128
139
|
|
|
@@ -180,6 +191,7 @@ Track = List[TrackRow]
|
|
|
180
191
|
Sensors = List[SensorRow]
|
|
181
192
|
|
|
182
193
|
Callsign = Annotated[str, mapped_column(CallsignString)]
|
|
194
|
+
Address = Annotated[str, mapped_column(AddressString)]
|
|
183
195
|
|
|
184
196
|
|
|
185
197
|
class Base(DeclarativeBase):
|
|
@@ -188,6 +200,7 @@ class Base(DeclarativeBase):
|
|
|
188
200
|
AirportCandidates: AirportCandidateType,
|
|
189
201
|
Track: TrackType,
|
|
190
202
|
Callsign: CallsignString,
|
|
203
|
+
Address: AddressString,
|
|
191
204
|
Sensors: SensorsType,
|
|
192
205
|
}
|
|
193
206
|
|
|
@@ -196,7 +209,7 @@ class StateVectorsData4(Base):
|
|
|
196
209
|
__tablename__ = "state_vectors_data4"
|
|
197
210
|
|
|
198
211
|
time: Mapped[pd.Timestamp]
|
|
199
|
-
icao24: Mapped[
|
|
212
|
+
icao24: Mapped[Address]
|
|
200
213
|
lat: Mapped[float]
|
|
201
214
|
lon: Mapped[float]
|
|
202
215
|
velocity: Mapped[float]
|
|
@@ -218,7 +231,7 @@ class StateVectorsData4(Base):
|
|
|
218
231
|
class FlightsData4(Base):
|
|
219
232
|
__tablename__ = "flights_data4"
|
|
220
233
|
|
|
221
|
-
icao24: Mapped[
|
|
234
|
+
icao24: Mapped[Address]
|
|
222
235
|
firstseen: Mapped[pd.Timestamp]
|
|
223
236
|
estdepartureairport: Mapped[str]
|
|
224
237
|
lastseen: Mapped[pd.Timestamp]
|
|
@@ -243,7 +256,7 @@ class FlightsData4(Base):
|
|
|
243
256
|
class FlightsData5(Base):
|
|
244
257
|
__tablename__ = "flights_data5"
|
|
245
258
|
|
|
246
|
-
icao24: Mapped[
|
|
259
|
+
icao24: Mapped[Address]
|
|
247
260
|
firstseen: Mapped[pd.Timestamp]
|
|
248
261
|
estdepartureairport: Mapped[str]
|
|
249
262
|
lastseen: Mapped[pd.Timestamp]
|
|
@@ -280,17 +293,7 @@ class RawTable(Protocol):
|
|
|
280
293
|
mintime: Mapped[pd.Timestamp]
|
|
281
294
|
maxtime: Mapped[pd.Timestamp]
|
|
282
295
|
msgcount: Mapped[int]
|
|
283
|
-
icao24: Mapped[
|
|
284
|
-
message: Mapped[str]
|
|
285
|
-
isid: Mapped[bool]
|
|
286
|
-
flightstatus: Mapped[int]
|
|
287
|
-
downlinkrequest: Mapped[int]
|
|
288
|
-
utilitymsg: Mapped[int]
|
|
289
|
-
interrogatorid: Mapped[int]
|
|
290
|
-
identifierdesignator: Mapped[int]
|
|
291
|
-
valuecode: Mapped[int]
|
|
292
|
-
altitude: Mapped[float]
|
|
293
|
-
identity: Mapped[str]
|
|
296
|
+
icao24: Mapped[Address]
|
|
294
297
|
|
|
295
298
|
# Whatever, we pick this one as primary key BUT
|
|
296
299
|
# - this is not true
|
|
@@ -306,7 +309,7 @@ class AcasData4(Base):
|
|
|
306
309
|
mintime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
307
310
|
maxtime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
308
311
|
msgcount: Mapped[int]
|
|
309
|
-
icao24: Mapped[
|
|
312
|
+
icao24: Mapped[Address]
|
|
310
313
|
message: Mapped[str]
|
|
311
314
|
isid: Mapped[bool]
|
|
312
315
|
flightstatus: Mapped[int]
|
|
@@ -332,7 +335,7 @@ class AllcallRepliesData4(Base):
|
|
|
332
335
|
mintime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
333
336
|
maxtime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
334
337
|
msgcount: Mapped[int]
|
|
335
|
-
icao24: Mapped[
|
|
338
|
+
icao24: Mapped[Address]
|
|
336
339
|
message: Mapped[str]
|
|
337
340
|
isid: Mapped[bool]
|
|
338
341
|
flightstatus: Mapped[int]
|
|
@@ -358,16 +361,9 @@ class IdentificationData4(Base):
|
|
|
358
361
|
mintime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
359
362
|
maxtime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
360
363
|
msgcount: Mapped[int]
|
|
361
|
-
icao24: Mapped[
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
flightstatus: Mapped[int]
|
|
365
|
-
downlinkrequest: Mapped[int]
|
|
366
|
-
utilitymsg: Mapped[int]
|
|
367
|
-
interrogatorid: Mapped[int]
|
|
368
|
-
identifierdesignator: Mapped[int]
|
|
369
|
-
valuecode: Mapped[int]
|
|
370
|
-
altitude: Mapped[float]
|
|
364
|
+
icao24: Mapped[Address]
|
|
365
|
+
emittercategory: Mapped[int]
|
|
366
|
+
ftc: Mapped[int]
|
|
371
367
|
identity: Mapped[str]
|
|
372
368
|
|
|
373
369
|
# Whatever, we pick this one as primary key BUT
|
|
@@ -385,16 +381,33 @@ class OperationalStatusData4(Base):
|
|
|
385
381
|
maxtime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
386
382
|
msgcount: Mapped[int]
|
|
387
383
|
icao24: Mapped[str]
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
384
|
+
subtypecode: Mapped[int]
|
|
385
|
+
unknowncapcode: Mapped[bool]
|
|
386
|
+
unknownopcode: Mapped[bool]
|
|
387
|
+
hasoperationaltcas: Mapped[int]
|
|
388
|
+
has1090esin: Mapped[bool]
|
|
389
|
+
supportsairreferencedvelocity: Mapped[int]
|
|
390
|
+
haslowtxpower: Mapped[int]
|
|
391
|
+
supportstargetstatereport: Mapped[int]
|
|
392
|
+
supportstargetchangereport: Mapped[int]
|
|
393
|
+
hasuatin: Mapped[bool]
|
|
394
|
+
nacv: Mapped[int]
|
|
395
|
+
nicsupplementc: Mapped[int]
|
|
396
|
+
hastcasresolutionadvisory: Mapped[bool]
|
|
397
|
+
hasactiveidentswitch: Mapped[bool]
|
|
398
|
+
usessingleantenna: Mapped[bool]
|
|
399
|
+
systemdesignassurance: Mapped[int]
|
|
400
|
+
gpsantennaoffset: Mapped[int]
|
|
401
|
+
airplanelength: Mapped[int]
|
|
402
|
+
airplanewidth: Mapped[float]
|
|
403
|
+
version: Mapped[int]
|
|
404
|
+
nicsupplementa: Mapped[bool]
|
|
405
|
+
positionnac: Mapped[float]
|
|
406
|
+
geometricverticalaccuracy: Mapped[int]
|
|
407
|
+
sourceintegritylevel: Mapped[int]
|
|
408
|
+
barometricaltitudeintegritycode: Mapped[int]
|
|
409
|
+
trackheadinginfo: Mapped[int]
|
|
410
|
+
horizontalreferencedirection: Mapped[bool]
|
|
398
411
|
|
|
399
412
|
# Whatever, we pick this one as primary key BUT
|
|
400
413
|
# - this is not true
|
|
@@ -410,7 +423,7 @@ class PositionData4(Base):
|
|
|
410
423
|
mintime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
411
424
|
maxtime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
412
425
|
msgcount: Mapped[int]
|
|
413
|
-
icao24: Mapped[
|
|
426
|
+
icao24: Mapped[Address]
|
|
414
427
|
nicsuppla: Mapped[bool]
|
|
415
428
|
hcr: Mapped[float]
|
|
416
429
|
nic: Mapped[int]
|
|
@@ -442,7 +455,7 @@ class RollcallRepliesData4(Base):
|
|
|
442
455
|
mintime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
443
456
|
maxtime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
444
457
|
msgcount: Mapped[int]
|
|
445
|
-
icao24: Mapped[
|
|
458
|
+
icao24: Mapped[Address]
|
|
446
459
|
message: Mapped[str]
|
|
447
460
|
isid: Mapped[bool]
|
|
448
461
|
flightstatus: Mapped[int]
|
|
@@ -468,17 +481,48 @@ class VelocityData4(Base):
|
|
|
468
481
|
mintime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
469
482
|
maxtime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
470
483
|
msgcount: Mapped[int]
|
|
471
|
-
icao24: Mapped[
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
484
|
+
icao24: Mapped[Address]
|
|
485
|
+
supersonic: Mapped[bool]
|
|
486
|
+
intentchange: Mapped[bool]
|
|
487
|
+
ifrcapability: Mapped[bool]
|
|
488
|
+
nac: Mapped[int]
|
|
489
|
+
ewvelocity: Mapped[float]
|
|
490
|
+
nsvelocity: Mapped[float]
|
|
491
|
+
baro: Mapped[bool]
|
|
492
|
+
vertrate: Mapped[float]
|
|
493
|
+
geominurbaro: Mapped[float] # typo confirmed
|
|
494
|
+
heading: Mapped[float]
|
|
495
|
+
velocity: Mapped[float]
|
|
496
|
+
|
|
497
|
+
# Whatever, we pick this one as primary key BUT
|
|
498
|
+
# - this is not true
|
|
499
|
+
# - we still need one column with a primary key
|
|
500
|
+
hour: Mapped[pd.Timestamp] = mapped_column(primary_key=True)
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
class FlarmRaw(Base):
|
|
504
|
+
__tablename__ = "flarm_raw"
|
|
505
|
+
|
|
506
|
+
sensortype: Mapped[str]
|
|
507
|
+
sensorlatitude: Mapped[float]
|
|
508
|
+
sensorlongitude: Mapped[float]
|
|
509
|
+
sensoraltitude: Mapped[int]
|
|
510
|
+
timeatserver: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
511
|
+
timeatsensor: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
512
|
+
timestamp: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
513
|
+
rawmessage: Mapped[str]
|
|
514
|
+
crc: Mapped[str]
|
|
515
|
+
rawsoftmessage: Mapped[str]
|
|
516
|
+
sensorname: Mapped[str]
|
|
517
|
+
ntperror: Mapped[float]
|
|
518
|
+
userfreqcorrection: Mapped[float]
|
|
519
|
+
autofreqcorrection: Mapped[float]
|
|
520
|
+
frequency: Mapped[float]
|
|
521
|
+
channel: Mapped[int]
|
|
522
|
+
snrdetector: Mapped[float]
|
|
523
|
+
snrdemodulator: Mapped[float]
|
|
524
|
+
typeogn: Mapped[bool]
|
|
525
|
+
crccorrect: Mapped[bool]
|
|
482
526
|
|
|
483
527
|
# Whatever, we pick this one as primary key BUT
|
|
484
528
|
# - this is not true
|
|
@@ -33,6 +33,7 @@ import pandas as pd
|
|
|
33
33
|
from .api import HasBounds, OpenSkyDBAPI
|
|
34
34
|
from .config import cache_path, trino_password, trino_username
|
|
35
35
|
from .schema import (
|
|
36
|
+
FlarmRaw,
|
|
36
37
|
FlightsData4,
|
|
37
38
|
FlightsData5,
|
|
38
39
|
RawTable,
|
|
@@ -119,6 +120,8 @@ class Trino(OpenSkyDBAPI):
|
|
|
119
120
|
if token is not None
|
|
120
121
|
else OAuth2Authentication(),
|
|
121
122
|
http_scheme="https",
|
|
123
|
+
# https://github.com/trinodb/trino-python-client/discussions/456
|
|
124
|
+
legacy_prepared_statements=True,
|
|
122
125
|
),
|
|
123
126
|
)
|
|
124
127
|
return engine
|
|
@@ -381,9 +384,11 @@ class Trino(OpenSkyDBAPI):
|
|
|
381
384
|
departure_airport: None | str = None,
|
|
382
385
|
arrival_airport: None | str = None,
|
|
383
386
|
airport: None | str = None,
|
|
387
|
+
time_buffer: None | str | pd.Timedelta = None,
|
|
384
388
|
cached: bool = True,
|
|
385
389
|
compress: bool = False,
|
|
386
390
|
limit: None | int = None,
|
|
391
|
+
selected_columns: tuple[InstrumentedAttribute[Any] | str, ...] = (),
|
|
387
392
|
**kwargs: Any,
|
|
388
393
|
) -> None | pd.DataFrame:
|
|
389
394
|
"""Get Traffic from the OpenSky Trino database.
|
|
@@ -413,6 +418,10 @@ class Trino(OpenSkyDBAPI):
|
|
|
413
418
|
:param bounds: sets a geographical footprint. Either an **airspace or
|
|
414
419
|
shapely shape** (requires the bounds attribute); or a **tuple of
|
|
415
420
|
float** (west, south, east, north);
|
|
421
|
+
:param selected_columns: specify the columns you want to retrieve. When
|
|
422
|
+
empty, use all columns of the StateVectorsData4 table. You may
|
|
423
|
+
escape column names as str. **Always** escape names from the
|
|
424
|
+
FlightsData4 table.
|
|
416
425
|
|
|
417
426
|
**Airports**
|
|
418
427
|
|
|
@@ -428,6 +437,10 @@ class Trino(OpenSkyDBAPI):
|
|
|
428
437
|
:param airport: a string for the ICAO identifier of the airport. Selects
|
|
429
438
|
flights departing from or arriving at the airport between the two
|
|
430
439
|
timestamps;
|
|
440
|
+
:param time_buffer: (default: None) time buffer used to extend time
|
|
441
|
+
bounds for flights in the OpenSky flight tables: requests will get
|
|
442
|
+
flights between ``start - time_buffer`` and ``stop + time_buffer``.
|
|
443
|
+
If no airport is specified, the parameter is ignored.
|
|
431
444
|
|
|
432
445
|
.. warning::
|
|
433
446
|
|
|
@@ -475,7 +488,7 @@ class Trino(OpenSkyDBAPI):
|
|
|
475
488
|
)
|
|
476
489
|
.where(
|
|
477
490
|
FlightsData4.day >= start_ts.floor("1d"),
|
|
478
|
-
FlightsData4.day <=
|
|
491
|
+
FlightsData4.day <= stop_ts.ceil("1d"),
|
|
479
492
|
)
|
|
480
493
|
)
|
|
481
494
|
|
|
@@ -512,18 +525,26 @@ class Trino(OpenSkyDBAPI):
|
|
|
512
525
|
|
|
513
526
|
flight_query = flight_table.subquery()
|
|
514
527
|
fd4 = aliased(FlightsData4, alias=flight_query, adapt_on_names=True)
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
.
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
)
|
|
522
|
-
.
|
|
528
|
+
|
|
529
|
+
if isinstance(time_buffer, str):
|
|
530
|
+
time_buffer = pd.Timedelta(time_buffer)
|
|
531
|
+
|
|
532
|
+
stmt = select(StateVectorsData4).join(
|
|
533
|
+
flight_query,
|
|
534
|
+
(fd4.icao24 == StateVectorsData4.icao24)
|
|
535
|
+
& (fd4.callsign == StateVectorsData4.callsign),
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
if time_buffer is None:
|
|
539
|
+
stmt = stmt.where(
|
|
523
540
|
StateVectorsData4.time >= fd4.firstseen,
|
|
524
541
|
StateVectorsData4.time <= fd4.lastseen,
|
|
525
542
|
)
|
|
526
|
-
|
|
543
|
+
else:
|
|
544
|
+
stmt = stmt.where(
|
|
545
|
+
StateVectorsData4.time >= (fd4.firstseen - time_buffer),
|
|
546
|
+
StateVectorsData4.time <= (fd4.lastseen + time_buffer),
|
|
547
|
+
)
|
|
527
548
|
|
|
528
549
|
stmt = self.stmt_where_str(stmt, icao24, StateVectorsData4.icao24)
|
|
529
550
|
stmt = self.stmt_where_str(stmt, callsign, StateVectorsData4.callsign)
|
|
@@ -568,8 +589,86 @@ class Trino(OpenSkyDBAPI):
|
|
|
568
589
|
stmt = stmt.where(
|
|
569
590
|
StateVectorsData4.time >= start_ts,
|
|
570
591
|
StateVectorsData4.time <= stop_ts,
|
|
571
|
-
StateVectorsData4.hour >= start_ts.floor("
|
|
572
|
-
StateVectorsData4.hour < stop_ts.ceil("
|
|
592
|
+
StateVectorsData4.hour >= start_ts.floor("1h"),
|
|
593
|
+
StateVectorsData4.hour < stop_ts.ceil("1h"),
|
|
594
|
+
)
|
|
595
|
+
|
|
596
|
+
def transform_column(col: str) -> InstrumentedAttribute[Any]:
|
|
597
|
+
if "." in col:
|
|
598
|
+
table, column = col.split(".")
|
|
599
|
+
MATCH = {
|
|
600
|
+
"StateVectorsData4": StateVectorsData4,
|
|
601
|
+
"FlightsData4": fd4,
|
|
602
|
+
}
|
|
603
|
+
return getattr(MATCH[table], column) # type: ignore
|
|
604
|
+
if candidate := getattr(StateVectorsData4, col, None):
|
|
605
|
+
return candidate # type: ignore
|
|
606
|
+
if candidate := getattr(fd4, col, None):
|
|
607
|
+
return candidate # type: ignore
|
|
608
|
+
raise ValueError(f"Unknown column: {col}")
|
|
609
|
+
|
|
610
|
+
if len(selected_columns) > 0:
|
|
611
|
+
columns = (
|
|
612
|
+
transform_column(col) if isinstance(col, str) else col
|
|
613
|
+
for col in selected_columns
|
|
614
|
+
)
|
|
615
|
+
stmt = stmt.with_only_columns(*columns)
|
|
616
|
+
|
|
617
|
+
if limit is not None:
|
|
618
|
+
stmt = stmt.limit(limit)
|
|
619
|
+
|
|
620
|
+
res = self.query(stmt, cached=cached, compress=compress)
|
|
621
|
+
|
|
622
|
+
if res.shape[0] == 0:
|
|
623
|
+
return None
|
|
624
|
+
|
|
625
|
+
return res
|
|
626
|
+
|
|
627
|
+
def flarm(
|
|
628
|
+
self,
|
|
629
|
+
start: timelike,
|
|
630
|
+
stop: None | timelike = None,
|
|
631
|
+
*args: ColumnExpressionArgument[bool],
|
|
632
|
+
sensor_name: None | str | list[str] = None,
|
|
633
|
+
cached: bool = True,
|
|
634
|
+
compress: bool = False,
|
|
635
|
+
limit: None | int = None,
|
|
636
|
+
correct_only: bool = True,
|
|
637
|
+
extra_columns: tuple[InstrumentedAttribute[Any], ...] = (),
|
|
638
|
+
**kwargs: Any,
|
|
639
|
+
) -> None | pd.DataFrame:
|
|
640
|
+
start_ts = to_datetime(start)
|
|
641
|
+
stop_ts = (
|
|
642
|
+
to_datetime(stop)
|
|
643
|
+
if stop is not None
|
|
644
|
+
else start_ts + pd.Timedelta("1d")
|
|
645
|
+
)
|
|
646
|
+
stmt = select(FlarmRaw).with_only_columns(
|
|
647
|
+
FlarmRaw.sensoraltitude,
|
|
648
|
+
FlarmRaw.sensorlatitude,
|
|
649
|
+
FlarmRaw.sensorlongitude,
|
|
650
|
+
FlarmRaw.sensorname,
|
|
651
|
+
FlarmRaw.timestamp,
|
|
652
|
+
FlarmRaw.timeatserver,
|
|
653
|
+
FlarmRaw.timeatsensor,
|
|
654
|
+
FlarmRaw.rawmessage,
|
|
655
|
+
*extra_columns,
|
|
656
|
+
)
|
|
657
|
+
if correct_only:
|
|
658
|
+
stmt = stmt.where(FlarmRaw.crccorrect)
|
|
659
|
+
stmt = stmt.where(FlarmRaw.rawmessage.is_not(None))
|
|
660
|
+
|
|
661
|
+
if sensor_name is not None:
|
|
662
|
+
stmt = self.stmt_where_str(stmt, sensor_name, FlarmRaw.sensorname)
|
|
663
|
+
|
|
664
|
+
for condition in args:
|
|
665
|
+
stmt = stmt.where(condition)
|
|
666
|
+
|
|
667
|
+
stmt = stmt.where(
|
|
668
|
+
FlarmRaw.timestamp >= start_ts,
|
|
669
|
+
FlarmRaw.timestamp <= stop_ts,
|
|
670
|
+
FlarmRaw.hour >= start_ts.floor("1h"),
|
|
671
|
+
FlarmRaw.hour < stop_ts.ceil("1h"),
|
|
573
672
|
)
|
|
574
673
|
|
|
575
674
|
if limit is not None:
|
|
@@ -712,7 +811,7 @@ class Trino(OpenSkyDBAPI):
|
|
|
712
811
|
)
|
|
713
812
|
.where(
|
|
714
813
|
FlightsData4.day >= start_ts.floor("1d"),
|
|
715
|
-
FlightsData4.day <=
|
|
814
|
+
FlightsData4.day <= stop_ts.ceil("1d"),
|
|
716
815
|
)
|
|
717
816
|
)
|
|
718
817
|
|
|
@@ -766,8 +865,8 @@ class Trino(OpenSkyDBAPI):
|
|
|
766
865
|
)
|
|
767
866
|
.group_by(StateVectorsData4.icao24)
|
|
768
867
|
.where(
|
|
769
|
-
StateVectorsData4.hour >= start_ts.floor("
|
|
770
|
-
StateVectorsData4.hour <= stop_ts.ceil("
|
|
868
|
+
StateVectorsData4.hour >= start_ts.floor("1h"),
|
|
869
|
+
StateVectorsData4.hour <= stop_ts.ceil("1h"),
|
|
771
870
|
StateVectorsData4.time >= start_ts,
|
|
772
871
|
StateVectorsData4.time <= stop_ts,
|
|
773
872
|
)
|
|
@@ -819,8 +918,8 @@ class Trino(OpenSkyDBAPI):
|
|
|
819
918
|
stmt = stmt.where(
|
|
820
919
|
Table.mintime >= start_ts,
|
|
821
920
|
Table.mintime <= stop_ts,
|
|
822
|
-
Table.hour >= start_ts.floor("
|
|
823
|
-
Table.hour < stop_ts.ceil("
|
|
921
|
+
Table.hour >= start_ts.floor("1h"),
|
|
922
|
+
Table.hour < stop_ts.ceil("1h"),
|
|
824
923
|
)
|
|
825
924
|
|
|
826
925
|
if limit is not None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|