pyopensky 2.1__tar.gz → 2.2__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.1 → pyopensky-2.2}/PKG-INFO +7 -4
- {pyopensky-2.1 → pyopensky-2.2}/pyproject.toml +5 -2
- {pyopensky-2.1 → pyopensky-2.2}/readme.md +5 -3
- pyopensky-2.2/src/pyopensky/__init__.py +3 -0
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/api.py +1 -0
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/impala.py +8 -8
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/rest.py +8 -4
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/schema.py +19 -10
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/trino.py +12 -6
- pyopensky-2.1/src/pyopensky/__init__.py +0 -0
- {pyopensky-2.1 → pyopensky-2.2}/license.txt +0 -0
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/config.py +0 -0
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/py.typed +0 -0
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/s3.py +0 -0
- {pyopensky-2.1 → pyopensky-2.2}/src/pyopensky/time.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyopensky
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2
|
|
4
4
|
Summary: A Python interface for OpenSky database
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Xavier Olive
|
|
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.9
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.10
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
16
|
Requires-Dist: appdirs (>=1.4.4)
|
|
16
17
|
Requires-Dist: minio (>=7.1)
|
|
17
18
|
Requires-Dist: pandas (>=1.5)
|
|
@@ -27,6 +28,8 @@ Description-Content-Type: text/markdown
|
|
|
27
28
|
|
|
28
29
|
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
30
|
|
|
31
|
+
Full documentation on https://open-aviation.github.io/pyopensky
|
|
32
|
+
|
|
30
33
|
## Installation
|
|
31
34
|
|
|
32
35
|
```sh
|
|
@@ -72,7 +75,7 @@ print(opensky_config_dir)
|
|
|
72
75
|
|
|
73
76
|
## Usage
|
|
74
77
|
|
|
75
|
-
- from the REST API:
|
|
78
|
+
- from the [REST API](https://open-aviation.github.io/pyopensky/rest.html):
|
|
76
79
|
|
|
77
80
|
```python
|
|
78
81
|
from pyopensky.rest import REST
|
|
@@ -87,7 +90,7 @@ print(opensky_config_dir)
|
|
|
87
90
|
rest.departure(airport, begin, end)
|
|
88
91
|
```
|
|
89
92
|
|
|
90
|
-
- from the Impala shell (requires authentication):
|
|
93
|
+
- from the [Impala](https://open-aviation.github.io/pyopensky/impala.html) shell (requires authentication):
|
|
91
94
|
|
|
92
95
|
```python
|
|
93
96
|
from pyopensky.impala import Impala
|
|
@@ -99,7 +102,7 @@ print(opensky_config_dir)
|
|
|
99
102
|
impala.rawdata(start, stop, *, callsign, icao24, bounds)
|
|
100
103
|
```
|
|
101
104
|
|
|
102
|
-
- from the Trino
|
|
105
|
+
- from the [Trino](https://open-aviation.github.io/pyopensky/trino.html) database (requires authentication):
|
|
103
106
|
|
|
104
107
|
```python
|
|
105
108
|
from pyopensky.trino import Trino
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pyopensky"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.2"
|
|
4
4
|
description = "A Python interface for OpenSky database"
|
|
5
5
|
authors = ["Xavier Olive <git@xoolive.org>", "Junzi Sun <j.sun-1@tudelft.nl>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -24,13 +24,16 @@ paramiko = ">=2.7"
|
|
|
24
24
|
|
|
25
25
|
[tool.poetry.group.dev.dependencies]
|
|
26
26
|
pre-commit = ">=3.1.1"
|
|
27
|
-
black = ">=23.1.0"
|
|
28
27
|
mypy = ">=1.0.1"
|
|
29
28
|
ruff = ">=0.0.253"
|
|
30
29
|
pytest = ">=7.2.1"
|
|
31
30
|
ipykernel = ">=6.21.2"
|
|
32
31
|
types-requests = ">=2.28.11.15"
|
|
33
32
|
types-paramiko = ">=3.3.0.0"
|
|
33
|
+
Sphinx = ">=5.1"
|
|
34
|
+
sphinx-design = ">=0.4.1"
|
|
35
|
+
sphinx-rtd-theme = ">=0.5.2"
|
|
36
|
+
sphinx-autodoc-typehints = ">=1.17,!=1.21.4"
|
|
34
37
|
|
|
35
38
|
[build-system]
|
|
36
39
|
requires = ["poetry-core"]
|
|
@@ -2,6 +2,8 @@
|
|
|
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
|
|
6
|
+
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
7
9
|
```sh
|
|
@@ -47,7 +49,7 @@ print(opensky_config_dir)
|
|
|
47
49
|
|
|
48
50
|
## Usage
|
|
49
51
|
|
|
50
|
-
- from the REST API:
|
|
52
|
+
- from the [REST API](https://open-aviation.github.io/pyopensky/rest.html):
|
|
51
53
|
|
|
52
54
|
```python
|
|
53
55
|
from pyopensky.rest import REST
|
|
@@ -62,7 +64,7 @@ print(opensky_config_dir)
|
|
|
62
64
|
rest.departure(airport, begin, end)
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
- from the Impala shell (requires authentication):
|
|
67
|
+
- from the [Impala](https://open-aviation.github.io/pyopensky/impala.html) shell (requires authentication):
|
|
66
68
|
|
|
67
69
|
```python
|
|
68
70
|
from pyopensky.impala import Impala
|
|
@@ -74,7 +76,7 @@ print(opensky_config_dir)
|
|
|
74
76
|
impala.rawdata(start, stop, *, callsign, icao24, bounds)
|
|
75
77
|
```
|
|
76
78
|
|
|
77
|
-
- from the Trino
|
|
79
|
+
- from the [Trino](https://open-aviation.github.io/pyopensky/trino.html) database (requires authentication):
|
|
78
80
|
|
|
79
81
|
```python
|
|
80
82
|
from pyopensky.trino import Trino
|
|
@@ -50,6 +50,7 @@ class OpenSkyDBAPI(Protocol):
|
|
|
50
50
|
departure_airport: None | str = None,
|
|
51
51
|
arrival_airport: None | str = None,
|
|
52
52
|
airport: None | str = None,
|
|
53
|
+
time_buffer: None | str | pd.Timedelta = None,
|
|
53
54
|
cached: bool = True,
|
|
54
55
|
compress: bool = False,
|
|
55
56
|
limit: None | int = None,
|
|
@@ -656,12 +656,12 @@ class Impala(OpenSkyDBAPI):
|
|
|
656
656
|
departure_airport: None | str = None,
|
|
657
657
|
arrival_airport: None | str = None,
|
|
658
658
|
airport: None | str = None,
|
|
659
|
+
time_buffer: None | str | pd.Timedelta = None,
|
|
659
660
|
cached: bool = True,
|
|
660
661
|
compress: bool = False,
|
|
661
662
|
limit: None | int = None,
|
|
662
663
|
other_tables: str = "",
|
|
663
664
|
other_params: str = "",
|
|
664
|
-
time_buffer: None | str | pd.Timedelta = None,
|
|
665
665
|
progressbar: bool | ProgressbarType[Any] = True,
|
|
666
666
|
date_delta: timedelta = timedelta(hours=1),
|
|
667
667
|
count: bool = False,
|
|
@@ -711,6 +711,10 @@ class Impala(OpenSkyDBAPI):
|
|
|
711
711
|
:param airport: a string for the ICAO identifier of the airport. Selects
|
|
712
712
|
flights departing from or arriving at the airport between the two
|
|
713
713
|
timestamps;
|
|
714
|
+
:param time_buffer: (default: None) time buffer used to extend time
|
|
715
|
+
bounds for flights in the OpenSky flight tables: requests will get
|
|
716
|
+
flights between ``start - time_buffer`` and ``stop + time_buffer``.
|
|
717
|
+
If no airport is specified, the parameter is ignored.
|
|
714
718
|
|
|
715
719
|
.. warning::
|
|
716
720
|
|
|
@@ -728,10 +732,6 @@ class Impala(OpenSkyDBAPI):
|
|
|
728
732
|
received each record;
|
|
729
733
|
:param nautical_units: (default: True) convert data stored in Impala to
|
|
730
734
|
standard nautical units (ft, ft/min, knots).
|
|
731
|
-
:param time_buffer: (default: None) time buffer used to extend time
|
|
732
|
-
bounds for flights in the OpenSky flight tables: requests will get
|
|
733
|
-
flights between ``start - time_buffer`` and ``stop + time_buffer``.
|
|
734
|
-
If no airport is specified, the parameter is ignored.
|
|
735
735
|
:param cached: (default: True) switch to False to force a new request to
|
|
736
736
|
the database regardless of the cached files. This option also
|
|
737
737
|
deletes previous cache files;
|
|
@@ -804,7 +804,7 @@ class Impala(OpenSkyDBAPI):
|
|
|
804
804
|
else:
|
|
805
805
|
other_params += f"and RTRIM(callsign) REGEXP('{callsign}') "
|
|
806
806
|
|
|
807
|
-
elif callsign.find("%")
|
|
807
|
+
elif callsign.find("%") >= 0 or callsign.find("_") >= 0:
|
|
808
808
|
other_params += "and callsign ilike '{}' ".format(callsign)
|
|
809
809
|
else:
|
|
810
810
|
other_params += "and callsign='{:<8s}' ".format(callsign)
|
|
@@ -1010,7 +1010,7 @@ class Impala(OpenSkyDBAPI):
|
|
|
1010
1010
|
other_params += "and not typeogn "
|
|
1011
1011
|
|
|
1012
1012
|
if isinstance(sensor_name, str):
|
|
1013
|
-
if sensor_name.find("%") >
|
|
1013
|
+
if sensor_name.find("%") > -1 or sensor_name.find("_") > -1:
|
|
1014
1014
|
other_params += "and sensorname ilike '{}' ".format(sensor_name)
|
|
1015
1015
|
else:
|
|
1016
1016
|
other_params += "and sensorname='{:<8s}' ".format(sensor_name)
|
|
@@ -1241,7 +1241,7 @@ class Impala(OpenSkyDBAPI):
|
|
|
1241
1241
|
"supported at the moment."
|
|
1242
1242
|
)
|
|
1243
1243
|
if isinstance(callsign, str):
|
|
1244
|
-
if callsign.find("%") >
|
|
1244
|
+
if callsign.find("%") > -1 or callsign.find("_") > -1:
|
|
1245
1245
|
callsigns = "and callsign ilike '{}' ".format(callsign)
|
|
1246
1246
|
else:
|
|
1247
1247
|
callsigns = "and callsign='{:<8s}' ".format(callsign)
|
|
@@ -64,6 +64,7 @@ class REST:
|
|
|
64
64
|
| str
|
|
65
65
|
| HasBounds
|
|
66
66
|
| tuple[float, float, float, float] = None,
|
|
67
|
+
retry: int = 5,
|
|
67
68
|
) -> pd.DataFrame:
|
|
68
69
|
"""Returns the current state vectors from OpenSky REST API.
|
|
69
70
|
|
|
@@ -132,9 +133,12 @@ class REST:
|
|
|
132
133
|
columns.append("_")
|
|
133
134
|
r = pd.DataFrame.from_records(json["states"], columns=columns)
|
|
134
135
|
except Exception:
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
if retry > 0:
|
|
137
|
+
retry = retry - 1
|
|
138
|
+
_log.warning("Retrying in 10 seconds... {retry} more time")
|
|
139
|
+
time.sleep(10)
|
|
140
|
+
return self.states(own, bounds, retry=retry)
|
|
141
|
+
raise
|
|
138
142
|
|
|
139
143
|
return r.assign(
|
|
140
144
|
timestamp=lambda df: pd.to_datetime(
|
|
@@ -210,7 +214,7 @@ class REST:
|
|
|
210
214
|
c.raise_for_status()
|
|
211
215
|
json = c.json()
|
|
212
216
|
|
|
213
|
-
return tuple(json["route"])
|
|
217
|
+
return tuple(json["route"])
|
|
214
218
|
|
|
215
219
|
def aircraft(
|
|
216
220
|
self,
|
|
@@ -31,6 +31,8 @@ class UTCTimestampInteger(TypeDecorator[pd.Timestamp]):
|
|
|
31
31
|
value = pd.to_datetime(value, utc=True)
|
|
32
32
|
if isinstance(value, pd.Timestamp):
|
|
33
33
|
return int(value.timestamp())
|
|
34
|
+
if isinstance(value, pd.Timedelta):
|
|
35
|
+
return int(value.total_seconds())
|
|
34
36
|
return super().process_bind_param(value, dialect)
|
|
35
37
|
|
|
36
38
|
def process_result_value(
|
|
@@ -83,6 +85,7 @@ class CallsignString(TypeDecorator[str]):
|
|
|
83
85
|
operator.ne, # !=
|
|
84
86
|
sql_operators.eq,
|
|
85
87
|
sql_operators.ne,
|
|
88
|
+
sql_operators.in_op,
|
|
86
89
|
sql_operators.contains, # .in()
|
|
87
90
|
):
|
|
88
91
|
return self
|
|
@@ -408,16 +411,22 @@ class PositionData4(Base):
|
|
|
408
411
|
maxtime: Mapped[pd.Timestamp] = mapped_column(UTCTimestampFloat)
|
|
409
412
|
msgcount: Mapped[int]
|
|
410
413
|
icao24: Mapped[str]
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
414
|
+
nicsuppla: Mapped[bool]
|
|
415
|
+
hcr: Mapped[float]
|
|
416
|
+
nic: Mapped[int]
|
|
417
|
+
survstatus: Mapped[int]
|
|
418
|
+
nicsupplb: Mapped[bool]
|
|
419
|
+
odd: Mapped[bool]
|
|
420
|
+
baroalt: Mapped[bool]
|
|
421
|
+
lat: Mapped[float]
|
|
422
|
+
lon: Mapped[float]
|
|
423
|
+
alt: Mapped[float]
|
|
424
|
+
nicsupplc: Mapped[bool]
|
|
425
|
+
groundspeed: Mapped[float]
|
|
426
|
+
gsresolution: Mapped[float]
|
|
427
|
+
heading: Mapped[float]
|
|
428
|
+
timeflag: Mapped[bool]
|
|
429
|
+
surface: Mapped[bool]
|
|
421
430
|
|
|
422
431
|
# Whatever, we pick this one as primary key BUT
|
|
423
432
|
# - this is not true
|
|
@@ -22,6 +22,7 @@ from sqlalchemy import (
|
|
|
22
22
|
)
|
|
23
23
|
from sqlalchemy.orm import aliased
|
|
24
24
|
from sqlalchemy.orm.attributes import InstrumentedAttribute
|
|
25
|
+
from sqlalchemy.sql import ColumnExpressionArgument
|
|
25
26
|
from sqlalchemy.sql.expression import text
|
|
26
27
|
from tqdm import tqdm
|
|
27
28
|
from trino.auth import JWTAuthentication, OAuth2Authentication
|
|
@@ -224,7 +225,7 @@ class Trino(OpenSkyDBAPI):
|
|
|
224
225
|
self,
|
|
225
226
|
start: timelike,
|
|
226
227
|
stop: None | timelike = None,
|
|
227
|
-
*args:
|
|
228
|
+
*args: ColumnExpressionArgument[bool],
|
|
228
229
|
departure_airport: None | str | list[str] = None,
|
|
229
230
|
arrival_airport: None | str | list[str] = None,
|
|
230
231
|
airport: None | str | list[str] = None,
|
|
@@ -345,6 +346,9 @@ class Trino(OpenSkyDBAPI):
|
|
|
345
346
|
Table.day < stop_ts.ceil("1d"),
|
|
346
347
|
)
|
|
347
348
|
|
|
349
|
+
for condition in args:
|
|
350
|
+
stmt = stmt.where(condition)
|
|
351
|
+
|
|
348
352
|
if limit is not None:
|
|
349
353
|
stmt = stmt.limit(limit)
|
|
350
354
|
|
|
@@ -364,7 +368,7 @@ class Trino(OpenSkyDBAPI):
|
|
|
364
368
|
self,
|
|
365
369
|
start: timelike,
|
|
366
370
|
stop: None | timelike = None,
|
|
367
|
-
*args:
|
|
371
|
+
*args: ColumnExpressionArgument[bool],
|
|
368
372
|
# date_delta: timedelta = timedelta(hours=1),
|
|
369
373
|
callsign: None | str | list[str] = None,
|
|
370
374
|
icao24: None | str | list[str] = None,
|
|
@@ -581,7 +585,7 @@ class Trino(OpenSkyDBAPI):
|
|
|
581
585
|
self,
|
|
582
586
|
start: timelike,
|
|
583
587
|
stop: None | timelike = None,
|
|
584
|
-
*args:
|
|
588
|
+
*args: ColumnExpressionArgument[bool],
|
|
585
589
|
icao24: None | str | list[str] = None,
|
|
586
590
|
serials: None | int | Iterable[int] = None,
|
|
587
591
|
bounds: None | HasBounds | tuple[float, float, float, float] = None,
|
|
@@ -593,6 +597,7 @@ class Trino(OpenSkyDBAPI):
|
|
|
593
597
|
compress: bool = False,
|
|
594
598
|
limit: None | int = None,
|
|
595
599
|
Table: Type[RawTable] = RollcallRepliesData4,
|
|
600
|
+
extra_columns: tuple[InstrumentedAttribute[Any], ...] = (),
|
|
596
601
|
**kwargs: Any,
|
|
597
602
|
) -> None | pd.DataFrame:
|
|
598
603
|
"""Get raw message from the OpenSky Trino database.
|
|
@@ -687,11 +692,9 @@ class Trino(OpenSkyDBAPI):
|
|
|
687
692
|
select(Table)
|
|
688
693
|
.with_only_columns(
|
|
689
694
|
Table.mintime,
|
|
690
|
-
Table.maxtime,
|
|
691
695
|
Table.rawmsg,
|
|
692
|
-
Table.msgcount,
|
|
693
696
|
Table.icao24,
|
|
694
|
-
|
|
697
|
+
*extra_columns,
|
|
695
698
|
)
|
|
696
699
|
.where(Table.rawmsg.is_not(None))
|
|
697
700
|
)
|
|
@@ -807,6 +810,9 @@ class Trino(OpenSkyDBAPI):
|
|
|
807
810
|
)
|
|
808
811
|
)
|
|
809
812
|
|
|
813
|
+
for condition in args:
|
|
814
|
+
stmt = stmt.where(condition)
|
|
815
|
+
|
|
810
816
|
stmt = self.stmt_where_str(stmt, icao24, Table.icao24)
|
|
811
817
|
|
|
812
818
|
stmt = stmt.where(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|