RemoteRF 2.1.10__tar.gz → 2.2.1__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.
- {remoterf-2.1.10/src/remoterf.egg-info → remoterf-2.2.1}/PKG-INFO +15 -15
- {remoterf-2.1.10 → remoterf-2.2.1}/README.md +14 -14
- {remoterf-2.1.10 → remoterf-2.2.1}/pyproject.toml +4 -4
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/config/config.py +1 -1
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/app.py +5 -6
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/direct_path.py +15 -6
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/grpc_client.py +4 -3
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/dynamic_device.py +8 -8
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/dynamic_v2.py +1 -1
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/ti_mmwave/__init__.py +1 -1
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/ti_mmwave/ti_mmwave_remote.py +1 -1
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/remoterf_cli.py +46 -32
- {remoterf-2.1.10 → remoterf-2.2.1/src/remoterf.egg-info}/PKG-INFO +15 -15
- remoterf-2.2.1/src/remoterf.egg-info/SOURCES.txt +93 -0
- remoterf-2.2.1/src/remoterf.egg-info/entry_points.txt +2 -0
- remoterf-2.2.1/src/remoterf.egg-info/top_level.txt +1 -0
- remoterf-2.1.10/src/remoteRF.py → remoterf-2.2.1/src/remoterf.py +9 -9
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_banner.py +5 -5
- remoterf-2.2.1/tests/test_cli_login_fresh.py +82 -0
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_config_address.py +1 -1
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_deployment_accounts.py +26 -26
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_direct_path_fixed.py +3 -3
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_direct_path_partner.py +3 -3
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_direct_path_race.py +4 -4
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_dynamic_device_codegen.py +29 -29
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_dynamic_v2.py +24 -12
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_federated_devices.py +7 -7
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_fetch_idl_fallback.py +7 -7
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_finish_prompt.py +3 -3
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_gate_i_direct_path.py +56 -10
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_grpc_client_target.py +4 -4
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_homes.py +57 -29
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_native_account_credentials.py +3 -3
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_native_devices.py +2 -2
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_partner_dynamic_v2.py +6 -6
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_pluto_virtual.py +3 -3
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_process_arg.py +4 -4
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_remoterf_cli.py +7 -7
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_ti_mmwave.py +12 -12
- {remoterf-2.1.10 → remoterf-2.2.1}/tests/test_upgrade_rescue.py +12 -12
- remoterf-2.1.10/src/remoterf.egg-info/SOURCES.txt +0 -93
- remoterf-2.1.10/src/remoterf.egg-info/entry_points.txt +0 -2
- remoterf-2.1.10/src/remoterf.egg-info/top_level.txt +0 -1
- remoterf-2.1.10/tests/test_cli_login_fresh.py +0 -54
- {remoterf-2.1.10 → remoterf-2.2.1}/LICENSE +0 -0
- {remoterf-2.1.10 → remoterf-2.2.1}/setup.cfg +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/grpc/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/grpc/deployment_capabilities.proto +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/grpc/deployment_capabilities_pb2.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/grpc/deployment_capabilities_pb2_grpc.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/grpc/grpc.proto +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/grpc/grpc_pb2.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/grpc/grpc_pb2_grpc.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/grpc/v2_codec.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/tos_notice.txt +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/utils/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/utils/ansi_codes.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/utils/api_token.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/utils/banner.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/utils/list_string.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/common/utils/process_arg.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/config/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/config/cert_fetcher.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/acc_login.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/banner_note.txt +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/dynamic_v2_transport.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/grpc_acc.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/secure_channel.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/core/v2_errors.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/deployment/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/deployment/backend.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/deployment/direct.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/deployment/homes.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/deployment/http.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/deployment/state.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/_virtual.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/adalm_pluto/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/adalm_pluto/adalm_pluto_remote.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/hackrf/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/hackrf/hackrf_remote.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/rtl_sdr/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/rtl_sdr/rtl_sdr_remote.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/sim_sdr/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/sim_sdr/sim_sdr_remote.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/support/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/support/ti_mmwave.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/support/uhd.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/support/uhd_dsp.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/support/uhd_v2.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/usrp/__init__.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/usrp/usrp_remote.py +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/usrp/usrp_remote.pyi +0 -0
- {remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/version.py +0 -0
- {remoterf-2.1.10 → remoterf-2.2.1}/src/remoterf.egg-info/dependency_links.txt +0 -0
- {remoterf-2.1.10 → remoterf-2.2.1}/src/remoterf.egg-info/requires.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: remoterf
|
|
3
|
-
Version: 2.1
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: A python API to remotely access signal centric hardware. Client-side only! Courtesy of Wireless Lab @ UCLA & Prof. Ian Roberts.
|
|
5
5
|
Author-email: Ethan Ge <ethoGalaxy@gmail.com>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -43,13 +43,13 @@ python --version
|
|
|
43
43
|
|
|
44
44
|
## Installation
|
|
45
45
|
|
|
46
|
-
Use the package manager [pip](https://pip.pypa.io/en/stable/) to install
|
|
46
|
+
Use the package manager [pip](https://pip.pypa.io/en/stable/) to install remoterf. It is recommended that you install this package within a [virtual environment](https://docs.python.org/3/library/venv.html).
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
49
|
python3 -m venv venv # Create virtual environment
|
|
50
50
|
source venv/bin/activate # Activate virtual environment
|
|
51
51
|
|
|
52
|
-
pip install remoterf # Install
|
|
52
|
+
pip install remoterf # Install remoterf
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
## NI USRP-2901, Ettus B205-mini, B200-family, and USRP N210
|
|
@@ -64,7 +64,7 @@ After reserving a server-local `usrp` inventory entry, fetch or refresh its
|
|
|
64
64
|
Dynamic v2 package with the reservation token:
|
|
65
65
|
|
|
66
66
|
```python
|
|
67
|
-
from
|
|
67
|
+
from remoterf.drivers import ensure_driver
|
|
68
68
|
|
|
69
69
|
ensure_driver(token="reservation-token")
|
|
70
70
|
```
|
|
@@ -72,7 +72,7 @@ ensure_driver(token="reservation-token")
|
|
|
72
72
|
Both supported initialization forms then use the same generated runtime:
|
|
73
73
|
|
|
74
74
|
```python
|
|
75
|
-
from
|
|
75
|
+
from remoterf.drivers.usrp import uhd
|
|
76
76
|
|
|
77
77
|
with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
|
|
78
78
|
print(usrp.remoterf_capabilities)
|
|
@@ -80,7 +80,7 @@ with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
|
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
```python
|
|
83
|
-
from
|
|
83
|
+
from remoterf.drivers.usrp import MultiUSRP
|
|
84
84
|
|
|
85
85
|
usrp = MultiUSRP("reservation-token")
|
|
86
86
|
try:
|
|
@@ -94,7 +94,7 @@ leading region reported by native UHD is changed on a partial receive:
|
|
|
94
94
|
|
|
95
95
|
```python
|
|
96
96
|
import numpy as np
|
|
97
|
-
from
|
|
97
|
+
from remoterf.drivers.usrp import uhd
|
|
98
98
|
|
|
99
99
|
with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
|
|
100
100
|
stream_args = uhd.usrp.StreamArgs("fc32", "sc16")
|
|
@@ -108,7 +108,7 @@ with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
|
|
|
108
108
|
|
|
109
109
|
The generated package includes native-like namespaces, aliases, overload
|
|
110
110
|
stubs, deterministic `close()`, context managers, opaque session-bound
|
|
111
|
-
handles, and typed errors in `
|
|
111
|
+
handles, and typed errors in `remoterf.core.v2_errors`. Streamers are never
|
|
112
112
|
silently recreated after a disconnect; reopen a new device session and
|
|
113
113
|
configure a new stream explicitly.
|
|
114
114
|
|
|
@@ -123,12 +123,12 @@ RTL-SDR clients are generated from the server's `rtl_sdr` schema. The machine
|
|
|
123
123
|
running client code does not need `librtlsdr` or PyRtlSdr:
|
|
124
124
|
|
|
125
125
|
```python
|
|
126
|
-
from
|
|
126
|
+
from remoterf.drivers import ensure_driver
|
|
127
127
|
|
|
128
128
|
token = "reservation-token"
|
|
129
129
|
ensure_driver(token=token)
|
|
130
130
|
|
|
131
|
-
from
|
|
131
|
+
from remoterf.drivers.rtl_sdr import RtlSdr
|
|
132
132
|
|
|
133
133
|
sdr = RtlSdr(token)
|
|
134
134
|
sdr.sample_rate = 2_048_000
|
|
@@ -160,12 +160,12 @@ machine physically connected to the radar needs `pyserial` or a CP210x driver.
|
|
|
160
160
|
The initial parser profile supports xWR68xx mmWave SDK 3 out-of-box TLV output.
|
|
161
161
|
|
|
162
162
|
```python
|
|
163
|
-
from
|
|
163
|
+
from remoterf.drivers import ensure_driver
|
|
164
164
|
|
|
165
165
|
token = "reservation-token"
|
|
166
166
|
ensure_driver(token=token)
|
|
167
167
|
|
|
168
|
-
from
|
|
168
|
+
from remoterf.drivers.ti_mmwave import TiMmWave, decode_frame
|
|
169
169
|
|
|
170
170
|
radar = TiMmWave(token)
|
|
171
171
|
print(radar.device_info)
|
|
@@ -323,7 +323,7 @@ Here is a explained sample script to get you going!
|
|
|
323
323
|
#### Python Script:
|
|
324
324
|
|
|
325
325
|
```python
|
|
326
|
-
from
|
|
326
|
+
from remoterf.drivers.adalm_pluto import * # Imports device Pluto SDR remote drivers. Change depending on desired device.
|
|
327
327
|
|
|
328
328
|
sdr = adi.Pluto( # Device initialization.
|
|
329
329
|
token = 'example_token' # Place the prior token here.
|
|
@@ -332,12 +332,12 @@ sdr = adi.Pluto( # Device initialization.
|
|
|
332
332
|
# You can now use this 'sdr' as you normally would with the default Pluto drivers.
|
|
333
333
|
```
|
|
334
334
|
|
|
335
|
-
If converting a existing `non-
|
|
335
|
+
If converting a existing `non-remoterf` compatible script:
|
|
336
336
|
|
|
337
337
|
```diff
|
|
338
338
|
- import existing_device_drivers
|
|
339
339
|
|
|
340
|
-
+ from
|
|
340
|
+
+ from remoterf.drivers.device_drivers import *
|
|
341
341
|
|
|
342
342
|
- device = device(init)
|
|
343
343
|
|
|
@@ -18,13 +18,13 @@ python --version
|
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
21
|
-
Use the package manager [pip](https://pip.pypa.io/en/stable/) to install
|
|
21
|
+
Use the package manager [pip](https://pip.pypa.io/en/stable/) to install remoterf. It is recommended that you install this package within a [virtual environment](https://docs.python.org/3/library/venv.html).
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
python3 -m venv venv # Create virtual environment
|
|
25
25
|
source venv/bin/activate # Activate virtual environment
|
|
26
26
|
|
|
27
|
-
pip install remoterf # Install
|
|
27
|
+
pip install remoterf # Install remoterf
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
## NI USRP-2901, Ettus B205-mini, B200-family, and USRP N210
|
|
@@ -39,7 +39,7 @@ After reserving a server-local `usrp` inventory entry, fetch or refresh its
|
|
|
39
39
|
Dynamic v2 package with the reservation token:
|
|
40
40
|
|
|
41
41
|
```python
|
|
42
|
-
from
|
|
42
|
+
from remoterf.drivers import ensure_driver
|
|
43
43
|
|
|
44
44
|
ensure_driver(token="reservation-token")
|
|
45
45
|
```
|
|
@@ -47,7 +47,7 @@ ensure_driver(token="reservation-token")
|
|
|
47
47
|
Both supported initialization forms then use the same generated runtime:
|
|
48
48
|
|
|
49
49
|
```python
|
|
50
|
-
from
|
|
50
|
+
from remoterf.drivers.usrp import uhd
|
|
51
51
|
|
|
52
52
|
with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
|
|
53
53
|
print(usrp.remoterf_capabilities)
|
|
@@ -55,7 +55,7 @@ with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
|
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
```python
|
|
58
|
-
from
|
|
58
|
+
from remoterf.drivers.usrp import MultiUSRP
|
|
59
59
|
|
|
60
60
|
usrp = MultiUSRP("reservation-token")
|
|
61
61
|
try:
|
|
@@ -69,7 +69,7 @@ leading region reported by native UHD is changed on a partial receive:
|
|
|
69
69
|
|
|
70
70
|
```python
|
|
71
71
|
import numpy as np
|
|
72
|
-
from
|
|
72
|
+
from remoterf.drivers.usrp import uhd
|
|
73
73
|
|
|
74
74
|
with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
|
|
75
75
|
stream_args = uhd.usrp.StreamArgs("fc32", "sc16")
|
|
@@ -83,7 +83,7 @@ with uhd.usrp.MultiUSRP(token="reservation-token") as usrp:
|
|
|
83
83
|
|
|
84
84
|
The generated package includes native-like namespaces, aliases, overload
|
|
85
85
|
stubs, deterministic `close()`, context managers, opaque session-bound
|
|
86
|
-
handles, and typed errors in `
|
|
86
|
+
handles, and typed errors in `remoterf.core.v2_errors`. Streamers are never
|
|
87
87
|
silently recreated after a disconnect; reopen a new device session and
|
|
88
88
|
configure a new stream explicitly.
|
|
89
89
|
|
|
@@ -98,12 +98,12 @@ RTL-SDR clients are generated from the server's `rtl_sdr` schema. The machine
|
|
|
98
98
|
running client code does not need `librtlsdr` or PyRtlSdr:
|
|
99
99
|
|
|
100
100
|
```python
|
|
101
|
-
from
|
|
101
|
+
from remoterf.drivers import ensure_driver
|
|
102
102
|
|
|
103
103
|
token = "reservation-token"
|
|
104
104
|
ensure_driver(token=token)
|
|
105
105
|
|
|
106
|
-
from
|
|
106
|
+
from remoterf.drivers.rtl_sdr import RtlSdr
|
|
107
107
|
|
|
108
108
|
sdr = RtlSdr(token)
|
|
109
109
|
sdr.sample_rate = 2_048_000
|
|
@@ -135,12 +135,12 @@ machine physically connected to the radar needs `pyserial` or a CP210x driver.
|
|
|
135
135
|
The initial parser profile supports xWR68xx mmWave SDK 3 out-of-box TLV output.
|
|
136
136
|
|
|
137
137
|
```python
|
|
138
|
-
from
|
|
138
|
+
from remoterf.drivers import ensure_driver
|
|
139
139
|
|
|
140
140
|
token = "reservation-token"
|
|
141
141
|
ensure_driver(token=token)
|
|
142
142
|
|
|
143
|
-
from
|
|
143
|
+
from remoterf.drivers.ti_mmwave import TiMmWave, decode_frame
|
|
144
144
|
|
|
145
145
|
radar = TiMmWave(token)
|
|
146
146
|
print(radar.device_info)
|
|
@@ -298,7 +298,7 @@ Here is a explained sample script to get you going!
|
|
|
298
298
|
#### Python Script:
|
|
299
299
|
|
|
300
300
|
```python
|
|
301
|
-
from
|
|
301
|
+
from remoterf.drivers.adalm_pluto import * # Imports device Pluto SDR remote drivers. Change depending on desired device.
|
|
302
302
|
|
|
303
303
|
sdr = adi.Pluto( # Device initialization.
|
|
304
304
|
token = 'example_token' # Place the prior token here.
|
|
@@ -307,12 +307,12 @@ sdr = adi.Pluto( # Device initialization.
|
|
|
307
307
|
# You can now use this 'sdr' as you normally would with the default Pluto drivers.
|
|
308
308
|
```
|
|
309
309
|
|
|
310
|
-
If converting a existing `non-
|
|
310
|
+
If converting a existing `non-remoterf` compatible script:
|
|
311
311
|
|
|
312
312
|
```diff
|
|
313
313
|
- import existing_device_drivers
|
|
314
314
|
|
|
315
|
-
+ from
|
|
315
|
+
+ from remoterf.drivers.device_drivers import *
|
|
316
316
|
|
|
317
317
|
- device = device(init)
|
|
318
318
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "remoterf"
|
|
7
|
-
version = "2.1
|
|
7
|
+
version = "2.2.1"
|
|
8
8
|
description = "A python API to remotely access signal centric hardware. Client-side only! Courtesy of Wireless Lab @ UCLA & Prof. Ian Roberts."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "GPL-3.0-or-later"
|
|
@@ -31,12 +31,12 @@ classifiers = [
|
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[project.scripts]
|
|
34
|
-
remoterf = "
|
|
34
|
+
remoterf = "remoterf.remoterf_cli:main"
|
|
35
35
|
|
|
36
36
|
[tool.setuptools]
|
|
37
37
|
package-dir = { "" = "src" }
|
|
38
|
-
# src/
|
|
39
|
-
py-modules = ["
|
|
38
|
+
# src/remoterf.py: see its docstring (upgrades from 2.0.14-2.1.x).
|
|
39
|
+
py-modules = ["remoterf"]
|
|
40
40
|
|
|
41
41
|
[tool.setuptools.packages.find]
|
|
42
42
|
where = ["src"]
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# You should have received a copy of the GNU General Public License
|
|
14
14
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
15
15
|
|
|
16
|
-
# src/
|
|
16
|
+
# src/remoterf/core/remoterf_config.py
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# You should have received a copy of the GNU General Public License
|
|
14
14
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
15
15
|
|
|
16
|
-
from
|
|
16
|
+
from remoterf.core.grpc_client import addr as server_addr, handle_admin_command
|
|
17
17
|
from . import *
|
|
18
18
|
from ..common.utils import *
|
|
19
19
|
|
|
@@ -536,10 +536,9 @@ def _federated_reservations_for_range(start_day, end_day):
|
|
|
536
536
|
|
|
537
537
|
def _federated_reserve_slot(device_id, chosen_day, chosen_slot, slot_start_str, slot_end_str):
|
|
538
538
|
handle = account.reserve_device(device_id, chosen_slot[0], chosen_slot[1])
|
|
539
|
-
|
|
540
|
-
printf("
|
|
541
|
-
printf("
|
|
542
|
-
printf("The first call can take ~20 s while the radio powers on.", Sty.GRAY)
|
|
539
|
+
# Worded as a lab account's reservation; the handle goes where a token goes.
|
|
540
|
+
printf("Reservation successful on device ", (Sty.BOLD, Sty.GREEN), f"{str(device_id).rsplit(':', 1)[-1]}", Sty.MAGENTA, " for ", Sty.DEFAULT, f"{chosen_day.strftime('%Y-%m-%d')} {slot_start_str}-{slot_end_str}.", Sty.CYAN)
|
|
541
|
+
printf("Your Token -> ", Sty.BOLD, f"{handle}", (Sty.BOLD, Sty.GREEN))
|
|
543
542
|
account.install_reserved_driver(handle, device_id)
|
|
544
543
|
|
|
545
544
|
|
|
@@ -1062,7 +1061,7 @@ def enroll(code=None):
|
|
|
1062
1061
|
# register. Here we are already logged in somewhere, so strip it -- and
|
|
1063
1062
|
# say so if it names a different lab than this one.
|
|
1064
1063
|
try:
|
|
1065
|
-
from
|
|
1064
|
+
from remoterf.deployment import homes
|
|
1066
1065
|
|
|
1067
1066
|
host, code = homes.parse_code(code)
|
|
1068
1067
|
except Exception: # noqa: BLE001 - not in that form; send as typed
|
|
@@ -50,11 +50,18 @@ import threading
|
|
|
50
50
|
import time
|
|
51
51
|
from typing import Callable, Optional
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
from
|
|
55
|
-
from aioquic.
|
|
56
|
-
from aioquic.quic
|
|
57
|
-
from aioquic.quic.
|
|
53
|
+
try:
|
|
54
|
+
from aioice import Candidate, Connection
|
|
55
|
+
from aioquic.asyncio.protocol import QuicConnectionProtocol
|
|
56
|
+
from aioquic.quic import events
|
|
57
|
+
from aioquic.quic.configuration import QuicConfiguration
|
|
58
|
+
from aioquic.quic.connection import QuicConnection
|
|
59
|
+
|
|
60
|
+
_BROKEN = None
|
|
61
|
+
except Exception as _exc: # noqa: BLE001 - e.g. conda swapped in a cryptography pip's pyOpenSSL cannot use
|
|
62
|
+
Candidate = Connection = QuicConnectionProtocol = QuicConfiguration = QuicConnection = object
|
|
63
|
+
events = None
|
|
64
|
+
_BROKEN = f"{type(_exc).__name__}: {_exc}"
|
|
58
65
|
|
|
59
66
|
from ..common.grpc import grpc_pb2
|
|
60
67
|
from ..common.utils import map_arg, unmap_arg
|
|
@@ -136,7 +143,7 @@ STUN_SECONDS = 1.5 # a STUN server answers in milliseconds or not at all
|
|
|
136
143
|
|
|
137
144
|
|
|
138
145
|
def enabled() -> bool:
|
|
139
|
-
return os.getenv("REMOTERF_DIRECT", "1").strip().lower() not in {"0", "off", "no", "false"}
|
|
146
|
+
return _BROKEN is None and os.getenv("REMOTERF_DIRECT", "1").strip().lower() not in {"0", "off", "no", "false"}
|
|
140
147
|
|
|
141
148
|
|
|
142
149
|
def wants(function_name: str) -> bool:
|
|
@@ -742,6 +749,8 @@ def current(token: Optional[str] = None) -> Optional[DirectPath]:
|
|
|
742
749
|
|
|
743
750
|
def describe() -> str:
|
|
744
751
|
"""What device calls use right now, for the shell."""
|
|
752
|
+
if _BROKEN is not None:
|
|
753
|
+
return f"relay (direct path unavailable: {_BROKEN}; fix: pip install --force-reinstall remoterf)"
|
|
745
754
|
if not enabled():
|
|
746
755
|
return "relay (direct path disabled: REMOTERF_DIRECT=0)"
|
|
747
756
|
path = _path
|
|
@@ -225,15 +225,16 @@ def _device_token(function_name, args):
|
|
|
225
225
|
def rpc_client(*, function_name, args, connection=None):
|
|
226
226
|
global tcp_calls
|
|
227
227
|
tcp_calls += 1
|
|
228
|
-
ref = _federated_ref(function_name, args) if connection is None else None
|
|
229
|
-
if ref is not None:
|
|
230
|
-
return _finish(_federated_call(ref, function_name, args))
|
|
231
228
|
wire = os.getenv("REMOTERF_RX_WIRE", "i16").strip().lower()
|
|
232
229
|
if wire and function_name.endswith(":rx:CALL0"):
|
|
233
230
|
# Gate I slice 3: c64 halves the samples on the wire, i16 (the default)
|
|
234
231
|
# quarters them when they are integer IQ; the driver still sees a complex
|
|
235
232
|
# array. REMOTERF_RX_WIRE="" or "c128" opts out (servers ignore unknown).
|
|
233
|
+
# Also through a HOME, whose relay caps each response at ~768 KiB.
|
|
236
234
|
args = {**args, "wire": map_arg(wire)}
|
|
235
|
+
ref = _federated_ref(function_name, args) if connection is None else None
|
|
236
|
+
if ref is not None:
|
|
237
|
+
return _finish(_federated_call(ref, function_name, args))
|
|
237
238
|
if connection is None and direct_path.wants(function_name):
|
|
238
239
|
path = direct_path.current(token=_device_token(function_name, args))
|
|
239
240
|
if path is not None:
|
|
@@ -24,7 +24,7 @@ When a device is reserved, call install_driver(device_id) to:
|
|
|
24
24
|
|
|
25
25
|
After install_driver() the user can do:
|
|
26
26
|
|
|
27
|
-
from
|
|
27
|
+
from remoterf.drivers.pluto import *
|
|
28
28
|
sdr = adi.Pluto(token)
|
|
29
29
|
|
|
30
30
|
On first device init, pass device_id to also check for schema updates:
|
|
@@ -158,7 +158,7 @@ def _client_class_name(schema: dict) -> str:
|
|
|
158
158
|
return str(schema.get("client_class") or _default_class_name(schema.get("device_type", "unknown")))
|
|
159
159
|
|
|
160
160
|
|
|
161
|
-
_CLIENT_MODULE_PREFIX = "
|
|
161
|
+
_CLIENT_MODULE_PREFIX = "remoterf.drivers.support."
|
|
162
162
|
_CLIENT_CTOR_SENTINELS = {"$self", "$result"}
|
|
163
163
|
_CLIENT_OBJECT_KINDS = {
|
|
164
164
|
"module",
|
|
@@ -1405,7 +1405,7 @@ _DRIVERS_DIR = Path(__file__).parent
|
|
|
1405
1405
|
|
|
1406
1406
|
def _write_driver_files(schema: dict) -> Path:
|
|
1407
1407
|
pkg_dir = _write_v2_driver_files(schema) if str(schema.get("schema_version")) == "2.0" else _write_v1_driver_files(schema)
|
|
1408
|
-
stale = f"
|
|
1408
|
+
stale = f"remoterf.drivers.{pkg_dir.name}"
|
|
1409
1409
|
for name in [m for m in sys.modules if m == stale or m.startswith(stale + ".")]:
|
|
1410
1410
|
del sys.modules[name]
|
|
1411
1411
|
return pkg_dir
|
|
@@ -1570,10 +1570,10 @@ def ensure_driver(*, token: str = None, device_id: int = None, device_name: str
|
|
|
1570
1570
|
the reservation (and therefore never had install_driver run automatically).
|
|
1571
1571
|
Pass the reservation token — the server resolves which device it belongs to.
|
|
1572
1572
|
|
|
1573
|
-
from
|
|
1573
|
+
from remoterf.drivers import ensure_driver
|
|
1574
1574
|
ensure_driver(token=token)
|
|
1575
1575
|
|
|
1576
|
-
from
|
|
1576
|
+
from remoterf.drivers.pluto import *
|
|
1577
1577
|
sdr = adi.Pluto(token)
|
|
1578
1578
|
|
|
1579
1579
|
One IDL:get_drivers RPC is always made (to resolve device_type and hash).
|
|
@@ -1611,7 +1611,7 @@ def ensure_driver(*, token: str = None, device_id: int = None, device_name: str
|
|
|
1611
1611
|
f"Driver for '{device_type}' updated "
|
|
1612
1612
|
f"(was {(current_hash or '?')[:16]}…, "
|
|
1613
1613
|
f"now {schema.get('schema_hash','?')[:16]}…).\n"
|
|
1614
|
-
f"Reimport before continuing: from
|
|
1614
|
+
f"Reimport before continuing: from remoterf.drivers.{device_type} import *"
|
|
1615
1615
|
)
|
|
1616
1616
|
|
|
1617
1617
|
|
|
@@ -1653,7 +1653,7 @@ def install_driver_if_stale(*, token: str, current_hash: str) -> bool:
|
|
|
1653
1653
|
If the driver was reinstalled, reimport the package before using the
|
|
1654
1654
|
new class:
|
|
1655
1655
|
|
|
1656
|
-
from
|
|
1656
|
+
from remoterf.drivers.pluto import *
|
|
1657
1657
|
"""
|
|
1658
1658
|
schema = fetch_idl(token=token, prefer_v2=True)
|
|
1659
1659
|
if schema.get("schema_hash") == current_hash:
|
|
@@ -1666,6 +1666,6 @@ def install_driver_if_stale(*, token: str, current_hash: str) -> bool:
|
|
|
1666
1666
|
print(
|
|
1667
1667
|
f"Driver for '{device_type}' updated "
|
|
1668
1668
|
f"(was {current_hash[:16]}…, now {schema.get('schema_hash','?')[:16]}…).\n"
|
|
1669
|
-
f"Reimport before continuing: from
|
|
1669
|
+
f"Reimport before continuing: from remoterf.drivers.{device_type} import *"
|
|
1670
1670
|
)
|
|
1671
1671
|
return True
|
|
@@ -678,7 +678,7 @@ def build_uhd_bindings(schema: dict, *, transport_factory=DynamicV2Transport):
|
|
|
678
678
|
if install_driver_if_stale(token=self.token, current_hash=schema["schema_hash"]):
|
|
679
679
|
raise RemoteRFProtocolError(
|
|
680
680
|
f"the server's {device_type} driver changed and the local copy "
|
|
681
|
-
f"was updated; reimport
|
|
681
|
+
f"was updated; reimport remoterf.drivers.{device_type} and retry",
|
|
682
682
|
details=dict(exc.details),
|
|
683
683
|
) from exc
|
|
684
684
|
raise
|
|
@@ -19,7 +19,7 @@ from . import ti_mmwave_remote as adi
|
|
|
19
19
|
from .ti_mmwave_remote import TiMmWave
|
|
20
20
|
|
|
21
21
|
__all__ = ["adi", "TiMmWave"]
|
|
22
|
-
ti_mmwave = _import_module("
|
|
22
|
+
ti_mmwave = _import_module("remoterf.drivers.support.ti_mmwave")
|
|
23
23
|
__all__.append("ti_mmwave")
|
|
24
24
|
if hasattr(ti_mmwave, "bind_client_class"):
|
|
25
25
|
ti_mmwave.bind_client_class("TiMmWave", TiMmWave)
|
{remoterf-2.1.10/src/remoteRF → remoterf-2.2.1/src/remoterf}/drivers/ti_mmwave/ti_mmwave_remote.py
RENAMED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
_PREFIX = "Ti_mmwave"
|
|
20
20
|
_SCHEMA_HASH = "sha256:320a89d95075a472d7899ff2f98b9fdee05c0be96fa5651bf5c4f0e5d276a1c4"
|
|
21
|
-
_CLIENT_MODULES = {'ti_mmwave': '
|
|
21
|
+
_CLIENT_MODULES = {'ti_mmwave': 'remoterf.drivers.support.ti_mmwave'}
|
|
22
22
|
_CLIENT_OBJECTS = {}
|
|
23
23
|
|
|
24
24
|
from importlib import import_module as _import_module
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# You should have received a copy of the GNU General Public License
|
|
14
14
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
15
15
|
|
|
16
|
-
# src/
|
|
16
|
+
# src/remoterf/cli.py
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
19
|
import argparse
|
|
@@ -39,10 +39,10 @@ def _installed_version() -> str:
|
|
|
39
39
|
|
|
40
40
|
def _connected_server(timeout_seconds: float = SERVER_CONNECT_TIMEOUT_SECONDS) -> str | None:
|
|
41
41
|
"""Return the configured endpoint only after its gRPC channel is ready."""
|
|
42
|
-
from
|
|
42
|
+
from remoterf.deployment.state import load_target
|
|
43
43
|
target = load_target()
|
|
44
44
|
if target and target['transport'] == 'https-json':
|
|
45
|
-
from
|
|
45
|
+
from remoterf.deployment.backend import selected_backend
|
|
46
46
|
backend = selected_backend()
|
|
47
47
|
try:
|
|
48
48
|
return backend.transport.origin
|
|
@@ -50,7 +50,7 @@ def _connected_server(timeout_seconds: float = SERVER_CONNECT_TIMEOUT_SECONDS) -
|
|
|
50
50
|
backend.close()
|
|
51
51
|
import grpc
|
|
52
52
|
|
|
53
|
-
from
|
|
53
|
+
from remoterf.core.grpc_client import active_endpoint, get_active_channel
|
|
54
54
|
|
|
55
55
|
try:
|
|
56
56
|
channel = get_active_channel()
|
|
@@ -97,8 +97,8 @@ def _read_dotenv_kv(path: Path) -> dict[str, str]:
|
|
|
97
97
|
return out
|
|
98
98
|
|
|
99
99
|
def _ensure_config_present() -> tuple[bool, str]:
|
|
100
|
-
from
|
|
101
|
-
from
|
|
100
|
+
from remoterf.deployment.state import load_target
|
|
101
|
+
from remoterf.deployment.direct import resolve_active_profile
|
|
102
102
|
target = load_target()
|
|
103
103
|
if target and target['transport'] == 'https-json':
|
|
104
104
|
return True, ''
|
|
@@ -189,7 +189,7 @@ def _account_shell(*, register: bool, enrollment_code: str | None = None,
|
|
|
189
189
|
if _connected_server() is None:
|
|
190
190
|
_print_server_unavailable()
|
|
191
191
|
return 2
|
|
192
|
-
from
|
|
192
|
+
from remoterf.core.acc_login import main as account_main
|
|
193
193
|
return int(
|
|
194
194
|
account_main(
|
|
195
195
|
register=register,
|
|
@@ -218,9 +218,9 @@ def _use_global(*, register: bool, show_banner: bool = True) -> int:
|
|
|
218
218
|
A Global-native account is complete on its own: it needs no deployment
|
|
219
219
|
HOME, and having one grants no access to any deployment.
|
|
220
220
|
"""
|
|
221
|
-
from
|
|
222
|
-
from
|
|
223
|
-
from
|
|
221
|
+
from remoterf.deployment import homes
|
|
222
|
+
from remoterf.deployment.backend import HttpsJsonAccountBackend
|
|
223
|
+
from remoterf.deployment.state import origin, select_target
|
|
224
224
|
|
|
225
225
|
try:
|
|
226
226
|
selected = origin(_global_origin())
|
|
@@ -249,7 +249,7 @@ def _working(label: str):
|
|
|
249
249
|
if not sys.stdout.isatty():
|
|
250
250
|
yield
|
|
251
251
|
return
|
|
252
|
-
from
|
|
252
|
+
from remoterf.common.utils.banner import supports_unicode
|
|
253
253
|
|
|
254
254
|
frames = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏" if supports_unicode() else "|/-\\"
|
|
255
255
|
stop = threading.Event()
|
|
@@ -294,7 +294,7 @@ def _reason(exc: BaseException) -> str:
|
|
|
294
294
|
|
|
295
295
|
|
|
296
296
|
def _use_home(name: str, *, register: bool, enrollment_code: str | None = None) -> int:
|
|
297
|
-
from
|
|
297
|
+
from remoterf.deployment import homes
|
|
298
298
|
|
|
299
299
|
try:
|
|
300
300
|
home = homes.load_home(name)
|
|
@@ -312,25 +312,39 @@ def _use_home(name: str, *, register: bool, enrollment_code: str | None = None)
|
|
|
312
312
|
)
|
|
313
313
|
|
|
314
314
|
|
|
315
|
+
def _agree_to_tos() -> bool:
|
|
316
|
+
"""Every registration is a fresh agreement, whoever is at the keyboard --
|
|
317
|
+
and starting one forgets the old agreement, so backing out here means
|
|
318
|
+
the next login asks too."""
|
|
319
|
+
from remoterf.config.config import _confirm_tos, forget_tos_agreement, remember_tos_agreement
|
|
320
|
+
|
|
321
|
+
forget_tos_agreement()
|
|
322
|
+
if not _confirm_tos("Do you agree to the RemoteRF Terms of Service? [y/N]: ",
|
|
323
|
+
"Registration cancelled."):
|
|
324
|
+
return False
|
|
325
|
+
remember_tos_agreement()
|
|
326
|
+
return True
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def _register_global() -> int:
|
|
330
|
+
"""`remoterf -r global`: straight to a Global account, same agreement as -r."""
|
|
331
|
+
print_client_banner(_installed_version(), server="")
|
|
332
|
+
if not _agree_to_tos():
|
|
333
|
+
return 1
|
|
334
|
+
return _use_global(register=True, show_banner=False)
|
|
335
|
+
|
|
336
|
+
|
|
315
337
|
def _register() -> int:
|
|
316
338
|
"""`remoterf -r`: a deployment enrollment code, or a Global account."""
|
|
317
339
|
from remoterf_federation_core import ValidationError
|
|
318
340
|
|
|
319
|
-
from
|
|
320
|
-
|
|
321
|
-
from remoteRF.config.config import _confirm_tos, forget_tos_agreement, remember_tos_agreement
|
|
341
|
+
from remoterf.deployment import homes
|
|
322
342
|
|
|
323
343
|
# The banner opens the session; the target is not known yet, so the shell
|
|
324
344
|
# below must not print it a second time.
|
|
325
345
|
print_client_banner(_installed_version(), server="")
|
|
326
|
-
|
|
327
|
-
# and starting one forgets the old agreement, so backing out here means
|
|
328
|
-
# the next login asks too.
|
|
329
|
-
forget_tos_agreement()
|
|
330
|
-
if not _confirm_tos("Do you agree to the RemoteRF Terms of Service? [y/N]: ",
|
|
331
|
-
"Registration cancelled."):
|
|
346
|
+
if not _agree_to_tos():
|
|
332
347
|
return 1
|
|
333
|
-
remember_tos_agreement()
|
|
334
348
|
try:
|
|
335
349
|
entered = input('Enrollment code (Enter for a RemoteRF Global account): ').strip()
|
|
336
350
|
except (EOFError, KeyboardInterrupt):
|
|
@@ -362,8 +376,8 @@ def _register() -> int:
|
|
|
362
376
|
|
|
363
377
|
|
|
364
378
|
def _login(target: str | None) -> int:
|
|
365
|
-
from
|
|
366
|
-
from
|
|
379
|
+
from remoterf.config.config import require_tos_for_login
|
|
380
|
+
from remoterf.deployment import homes
|
|
367
381
|
|
|
368
382
|
if not require_tos_for_login():
|
|
369
383
|
return 1
|
|
@@ -404,7 +418,7 @@ def _print_pick_a_target() -> int:
|
|
|
404
418
|
|
|
405
419
|
|
|
406
420
|
def _print_homes() -> int:
|
|
407
|
-
from
|
|
421
|
+
from remoterf.deployment import homes
|
|
408
422
|
|
|
409
423
|
homes.migrate_legacy_target()
|
|
410
424
|
saved = homes.homes()
|
|
@@ -434,8 +448,8 @@ def main() -> int:
|
|
|
434
448
|
return 0
|
|
435
449
|
|
|
436
450
|
if argv[0] in ("--register", "-register", "-r"):
|
|
437
|
-
if len(argv) == 2 and argv[1] == "global":
|
|
438
|
-
return
|
|
451
|
+
if len(argv) == 2 and argv[1].lstrip("-") == "global":
|
|
452
|
+
return _register_global()
|
|
439
453
|
if len(argv) > 1:
|
|
440
454
|
print("ERROR: --register takes no arguments (or 'global')")
|
|
441
455
|
return 2
|
|
@@ -451,14 +465,14 @@ def main() -> int:
|
|
|
451
465
|
return _print_homes()
|
|
452
466
|
|
|
453
467
|
if argv[0] in ("--version", "-version", "-v"):
|
|
454
|
-
from
|
|
468
|
+
from remoterf.version import main as version_main
|
|
455
469
|
|
|
456
470
|
print("RemoteRF version:", end=" ")
|
|
457
471
|
version_main()
|
|
458
472
|
return 0
|
|
459
473
|
|
|
460
474
|
if argv[0] in ("--config", "-config", "-c"):
|
|
461
|
-
from
|
|
475
|
+
from remoterf.config.config import configure, wipe_config
|
|
462
476
|
|
|
463
477
|
addr = None
|
|
464
478
|
wipe = False
|
|
@@ -527,13 +541,13 @@ def main() -> int:
|
|
|
527
541
|
return int(wipe_config(yes=yes))
|
|
528
542
|
|
|
529
543
|
if addr is not None:
|
|
530
|
-
from
|
|
544
|
+
from remoterf.deployment.state import origin, select_target, select_direct
|
|
531
545
|
# Explicit host:port (even with a scheme) remains direct by default.
|
|
532
546
|
stripped = addr.strip().split('://', 1)[-1]
|
|
533
547
|
use_https = account_transport == 'https-json' or (':' not in stripped and account_transport != 'grpc')
|
|
534
548
|
if use_https:
|
|
535
|
-
from
|
|
536
|
-
from
|
|
549
|
+
from remoterf.deployment.backend import HttpsJsonAccountBackend
|
|
550
|
+
from remoterf.config.config import _confirm_tos
|
|
537
551
|
try:
|
|
538
552
|
selected_origin = origin(addr)
|
|
539
553
|
if not _confirm_tos():
|