remoteRF-server 0.1.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.
- remoterf_server-0.1.0/PKG-INFO +9 -0
- remoterf_server-0.1.0/README.md +171 -0
- remoterf_server-0.1.0/pyproject.toml +27 -0
- remoterf_server-0.1.0/setup.cfg +4 -0
- remoterf_server-0.1.0/src/remoteRF_server/__init__.py +0 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/__init__.py +0 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/grpc/__init__.py +1 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/grpc/grpc_host_pb2.py +53 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +97 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/grpc/grpc_pb2.py +59 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +97 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/utils/__init__.py +5 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/utils/ansi_codes.py +120 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/utils/api_token.py +31 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/utils/db_connection.py +51 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/utils/list_string.py +5 -0
- remoterf_server-0.1.0/src/remoteRF_server/common/utils/process_arg.py +80 -0
- remoterf_server-0.1.0/src/remoteRF_server/drivers/__init__.py +0 -0
- remoterf_server-0.1.0/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
- remoterf_server-0.1.0/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +121 -0
- remoterf_server-0.1.0/src/remoteRF_server/host/__init__.py +0 -0
- remoterf_server-0.1.0/src/remoteRF_server/host/host_directory_store.py +160 -0
- remoterf_server-0.1.0/src/remoteRF_server/host/host_tunnel_server.py +828 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/__init__.py +0 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/acc_perms.py +315 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/cert_provider.py +242 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/device_manager.py +235 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/grpc_server.py +749 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/reservation.py +596 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/rpc_manager.py +38 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/user_group_cli.py +589 -0
- remoterf_server-0.1.0/src/remoteRF_server/server/user_group_handler.py +1113 -0
- remoterf_server-0.1.0/src/remoteRF_server/tools/__init__.py +191 -0
- remoterf_server-0.1.0/src/remoteRF_server/tools/cert_gen.py +190 -0
- remoterf_server-0.1.0/src/remoteRF_server.egg-info/PKG-INFO +9 -0
- remoterf_server-0.1.0/src/remoteRF_server.egg-info/SOURCES.txt +38 -0
- remoterf_server-0.1.0/src/remoteRF_server.egg-info/dependency_links.txt +1 -0
- remoterf_server-0.1.0/src/remoteRF_server.egg-info/entry_points.txt +3 -0
- remoterf_server-0.1.0/src/remoteRF_server.egg-info/requires.txt +6 -0
- remoterf_server-0.1.0/src/remoteRF_server.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Remote RF Linux Server
|
|
2
|
+
|
|
3
|
+
A python codebase to host the remoteRF Platform.
|
|
4
|
+
|
|
5
|
+
Courtesy of Wireless Lab @ UCLA. - Ethan Ge
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- **Local Linux Computer**: You will need a linux based machine to run the server, along with the networking that goes along with it.
|
|
10
|
+
|
|
11
|
+
- **Python 3.12**: Honestly I am not sure what minimum version is required. But 3.12 for sure works. If you don’t have Python installed, you can download it from the [official Python website](https://www.python.org/downloads/).
|
|
12
|
+
To check your current Python version, open a terminal and run:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
python --version
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- **Adalm Pluto Python Drivers**: You will need to install this if you wish to use the adalm pluto SDR. [Adalm Pluto Python Drivers](https://pysdr.org/content/pluto.html).
|
|
19
|
+
|
|
20
|
+
- **Other Devices**: At the moment, although a couple other devices are loosely supported, the Pluto is the only 'full support' device. More can be easily added though.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
### **Note**:
|
|
25
|
+
These instructions are confirmed to be working on Fedora LTS Server build. Although nothing should need changing on different distros, I cannot confirm nor deny that.
|
|
26
|
+
|
|
27
|
+
### **Clone Repo**:
|
|
28
|
+
First clone the server repo [here](https://github.com/WirelessLabAtUCLA/RemoteRF-Server).
|
|
29
|
+
|
|
30
|
+
### **Python Dependencies**:
|
|
31
|
+
Navigate to the cloned repo. Run the below commands. Mind that a python virtual environment `VENV` is recommended, although given device drivers, it may not be the easiest.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python3 -m venv venv # Create venv folder
|
|
35
|
+
source venv/bin/activate # Activate venv
|
|
36
|
+
|
|
37
|
+
pip install setuptools -e . # Auto installs dependencies
|
|
38
|
+
|
|
39
|
+
RRRFserver # Run Remote RF Server
|
|
40
|
+
```
|
|
41
|
+
If you have errors, such as `ModuleNotFoundError: No module named 'adi'`, yet you are able to use the adi package elsewhere, such as in the global interpreter, you will need to update your python path to include the adi package, which you should've installed earlier from [here](https://pysdr.org/content/pluto.html).
|
|
42
|
+
|
|
43
|
+
If you are too lazy to do so, you can just repeat the same steps but on the global python interpreter, which should solve the issue, albeit a less clean solution.
|
|
44
|
+
|
|
45
|
+
## Configuration
|
|
46
|
+
|
|
47
|
+
Now onto the configuration of the server for use. Server script needs to be restarted for config to take place.
|
|
48
|
+
|
|
49
|
+
### Network parameters:
|
|
50
|
+
The server requires a specified port as well as a manual IP to be set. You can do an online search for "how to input manual IP address for OS TYPE".
|
|
51
|
+
|
|
52
|
+
Navigate to `src/remoteRF_server/certs` directory.
|
|
53
|
+
```bash
|
|
54
|
+
cd src/remoteRF_server/certs # From repo root
|
|
55
|
+
|
|
56
|
+
openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt -subj "/CN=XXX.XX.XXX.XXX" -addext "subjectAltName=IP:XXX.XX.XXX.XXX" # Generate the certs. Replace XXX.XX.XXX.XXX with the server IP.
|
|
57
|
+
```
|
|
58
|
+
Navigate to `src/remoteRF_server/server/.env.server`.
|
|
59
|
+
```bash
|
|
60
|
+
GRPC_PORT='XXXXX' # Replace XXXXX with the server port.
|
|
61
|
+
```
|
|
62
|
+
Copy the internals of `/certs`, and replace the remoteRF-Client cert folder with these new certificates. This is done as **BOTH** the client and server need to have access to the same generated certificates for secure HTTPs transfer.
|
|
63
|
+
|
|
64
|
+
### Device parameters:
|
|
65
|
+
|
|
66
|
+
Navigate to `src/remoteRF_server/server/device_manager.py`. Scroll down until you see:
|
|
67
|
+
```python
|
|
68
|
+
devices = { # device, salt, hash
|
|
69
|
+
0: (connect_pluto(usb='1.6.5'), '', ''),
|
|
70
|
+
1: (connect_pluto(usb='1.7.5'), '', ''),
|
|
71
|
+
# ...
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
To add more devices, simply duplicate the item and increment the device id. You also need to configure the usb port. To find this value, run this in the terminal once you have connected your desired devices.
|
|
75
|
+
```bash
|
|
76
|
+
iio_info -s # displays usb port info
|
|
77
|
+
```
|
|
78
|
+
```bash
|
|
79
|
+
Available contexts:
|
|
80
|
+
0: (jc42,coretemp,pch_skylake,nouveau,acpitz,jc42,dell_smm,hidpp_battery_0,nvme on Dell Inc.) [local:]
|
|
81
|
+
1: 0456:b673 (Analog Devices Inc. PlutoSDR (ADALM-PLUTO)), serial=10447392da110010f9ff1500612ff8ecb0 [usb:1.6.5]
|
|
82
|
+
# Use this `usb:1.6.5` as the input for the device init
|
|
83
|
+
```
|
|
84
|
+
Under `devices` there is also `device_info`. Update this accordingly. This is what is displayed when users request to see what devices there are.
|
|
85
|
+
|
|
86
|
+
Remember to update default permissions and the like! Otherwise users won't be able to add the new devices.
|
|
87
|
+
|
|
88
|
+
### Permission parameters:
|
|
89
|
+
|
|
90
|
+
In the repo, navigate to `src/remoteRF_server/server/acc_perms.py`. You should see:
|
|
91
|
+
```python
|
|
92
|
+
class userperms:
|
|
93
|
+
def __init__(self): # default user perms settings
|
|
94
|
+
self.id = 'user'
|
|
95
|
+
self.max_reservations = 1
|
|
96
|
+
self.max_reservation_time_sec = 3600
|
|
97
|
+
self.devices_allowed = [0, 1] # device ID
|
|
98
|
+
```
|
|
99
|
+
Here, you can set the default user perms. This default is given to all 'normal users', and is also the permission level when users first make their accounts. For the other two tiers of users, they are configured on run time when the server is running. The server saves all run time changes so no data hypothetically can be lost.
|
|
100
|
+
|
|
101
|
+
### .Proto regen:
|
|
102
|
+
Only needed if, well, you need to update the base networking.
|
|
103
|
+
```bash
|
|
104
|
+
pip install --upgrade grpcio grpcio-tools protobuf
|
|
105
|
+
|
|
106
|
+
cd src/remoteRF_server/common/grpc
|
|
107
|
+
python -m grpc_tools.protoc \
|
|
108
|
+
-I=. \
|
|
109
|
+
--python_out=. \
|
|
110
|
+
--grpc_python_out=. \
|
|
111
|
+
grpc.proto
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Time to Serve!
|
|
115
|
+
|
|
116
|
+
Once your basic config is setup, you can begin testing the basics of the server!
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
RRRFserver # Start the server
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Given my weird setup, this is what I did to make it work:
|
|
123
|
+
New Terminal
|
|
124
|
+
cd Documents/GitHub/RemoteRF-Server
|
|
125
|
+
sudo pip install -e . (don't use pip3)
|
|
126
|
+
sudo RRRFserver
|
|
127
|
+
|
|
128
|
+
IF the changes you make don't seem to apply ...
|
|
129
|
+
which RRRFserver
|
|
130
|
+
What worked for me (if u accidently use pip3)
|
|
131
|
+
sudo python3 -m pip uninstall RemoteRF-Server (destroy pip3)
|
|
132
|
+
|
|
133
|
+
Bruh ....
|
|
134
|
+
|
|
135
|
+
python3 -m pip uninstall -y remoteRF_server RRRFserver || true
|
|
136
|
+
rm -f ~/.local/bin/RRRFserver
|
|
137
|
+
hash -r
|
|
138
|
+
|
|
139
|
+
python3 -m pip install -e . --user --force-reinstall
|
|
140
|
+
hash -r
|
|
141
|
+
|
|
142
|
+
Type `help` to see the list of commands. They are pretty self explanatory. Run them and try it out! You can use arrow keys to cycle commands.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
'exit' - Stop server.
|
|
146
|
+
'help' - Help.
|
|
147
|
+
'clear' - Clear terminal screen.
|
|
148
|
+
'printa' - Print all accounts
|
|
149
|
+
'printd' - Print all devices
|
|
150
|
+
'printp' - Print all perms
|
|
151
|
+
'printr' - Print all reservations
|
|
152
|
+
'rm aa' - Remove all accounts
|
|
153
|
+
'rm a' - Remove one account
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Follow the [README](https://github.com/WirelessLabAtUCLA/RemoteRF-Client/blob/main/README.md) on this repo to configure the client side.
|
|
157
|
+
|
|
158
|
+
I would suggest first trying to connect locally (on the same machine), and then remotely. You do not need the VPN if you are testing locally or on LAN. If all goes well, the server should be now ready for use!
|
|
159
|
+
|
|
160
|
+
**WARNING**: The current system distributes the private certificates. It is safe as UCLA wraps the network in a VPN, however if you open the server to all of the internet, this approach can be very dangerous.
|
|
161
|
+
|
|
162
|
+
## Troubleshooting
|
|
163
|
+
I had a variety of issues setting up the server. Here is a list of steps to take if the server refuses to connect:
|
|
164
|
+
|
|
165
|
+
### Server Certificates:
|
|
166
|
+
Confirm that the server certs were generated with the right IPs, and that the existing server certs weren't expired. If you are not sure how to check them, just regenerate them. Remember that if you do regenerate you will need to give the client a exact copy of those certs as well.
|
|
167
|
+
|
|
168
|
+
### Local Firewall:
|
|
169
|
+
Some distros come with default firewall settings that block traffic on specific ports. Make sure that your firewall settings permit traffic to and from the server.
|
|
170
|
+
|
|
171
|
+
- **ISP Firewall**: If doing this on UCLA Campus, they block and manage much of the traffic. You will need to submit a [Firewall Access Form](https://www.seasnet.ucla.edu/firewall-access-request/).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "remoteRF-server"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"grpcio",
|
|
10
|
+
"protobuf",
|
|
11
|
+
"numpy",
|
|
12
|
+
"prompt_toolkit",
|
|
13
|
+
"python-dotenv",
|
|
14
|
+
"grpcio-tools",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.scripts]
|
|
18
|
+
RRRFserver = "remoteRF_server.server.grpc_server:main"
|
|
19
|
+
RRRFcerts = "remoteRF_server.tools.cert_gen:main"
|
|
20
|
+
|
|
21
|
+
# RRRFcerts --ip XXX.XX.XXX.XXX --ca-days 7300 --days 3650 --force
|
|
22
|
+
|
|
23
|
+
[tool.setuptools]
|
|
24
|
+
package-dir = { "" = "src" }
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.packages.find]
|
|
27
|
+
where = ["src"]
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from . import grpc_pb2, grpc_pb2_grpc
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: grpc_host.proto
|
|
5
|
+
# Protobuf Python Version: 6.31.1
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
|
+
1,
|
|
17
|
+
'',
|
|
18
|
+
'grpc_host.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
import grpc_pb2 as grpc__pb2
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fgrpc_host.proto\x12\x08remoterf\x1a\ngrpc.proto\"-\n\tHostHello\x12\x0f\n\x07host_id\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\"^\n\nDeviceInfo\x12\x10\n\x08local_id\x18\x01 \x01(\r\x12\r\n\x05label\x18\x02 \x01(\t\x12\x11\n\tdevice_id\x18\x03 \x01(\t\x12\x0e\n\x06serial\x18\x04 \x01(\t\x12\x0c\n\x04kind\x18\x05 \x01(\t\"_\n\x0e\x44\x65viceAnnounce\x12%\n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x14.remoterf.DeviceInfo\x12\x0f\n\x07unix_ms\x18\x02 \x01(\x04\x12\x15\n\rfull_snapshot\x18\x03 \x01(\x08\"\xab\x01\n\nRpcRequest\x12\x0e\n\x06req_id\x18\x01 \x01(\t\x12\x18\n\x10global_device_id\x18\x02 \x01(\r\x12\x17\n\x0flocal_device_id\x18\x03 \x01(\r\x12\x11\n\tdevice_id\x18\x04 \x01(\t\x12-\n\x07request\x18\x05 \x01(\x0b\x32\x1c.remote_rf.GenericRPCRequest\x12\x18\n\x10\x64\x65\x61\x64line_unix_ms\x18\x06 \x01(\x04\"i\n\x0bRpcResponse\x12\x0e\n\x06req_id\x18\x01 \x01(\t\x12\n\n\x02ok\x18\x02 \x01(\x08\x12/\n\x08response\x18\x03 \x01(\x0b\x32\x1d.remote_rf.GenericRPCResponse\x12\r\n\x05\x65rror\x18\x04 \x01(\t\"\x1c\n\tHeartbeat\x12\x0f\n\x07unix_ms\x18\x01 \x01(\x04\"\x18\n\x06\x43\x61ncel\x12\x0e\n\x06req_id\x18\x01 \x01(\t\"\x97\x02\n\tHostFrame\x12$\n\x05hello\x18\x01 \x01(\x0b\x32\x13.remoterf.HostHelloH\x00\x12\x33\n\x0f\x64\x65vice_announce\x18\x02 \x01(\x0b\x32\x18.remoterf.DeviceAnnounceH\x00\x12+\n\x0brpc_request\x18\x03 \x01(\x0b\x32\x14.remoterf.RpcRequestH\x00\x12-\n\x0crpc_response\x18\x04 \x01(\x0b\x32\x15.remoterf.RpcResponseH\x00\x12(\n\theartbeat\x18\x05 \x01(\x0b\x32\x13.remoterf.HeartbeatH\x00\x12\"\n\x06\x63\x61ncel\x18\x06 \x01(\x0b\x32\x10.remoterf.CancelH\x00\x42\x05\n\x03msg2E\n\nHostTunnel\x12\x37\n\x07\x43onnect\x12\x13.remoterf.HostFrame\x1a\x13.remoterf.HostFrame(\x01\x30\x01\x62\x06proto3')
|
|
29
|
+
|
|
30
|
+
_globals = globals()
|
|
31
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
32
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'grpc_host_pb2', _globals)
|
|
33
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
34
|
+
DESCRIPTOR._loaded_options = None
|
|
35
|
+
_globals['_HOSTHELLO']._serialized_start=41
|
|
36
|
+
_globals['_HOSTHELLO']._serialized_end=86
|
|
37
|
+
_globals['_DEVICEINFO']._serialized_start=88
|
|
38
|
+
_globals['_DEVICEINFO']._serialized_end=182
|
|
39
|
+
_globals['_DEVICEANNOUNCE']._serialized_start=184
|
|
40
|
+
_globals['_DEVICEANNOUNCE']._serialized_end=279
|
|
41
|
+
_globals['_RPCREQUEST']._serialized_start=282
|
|
42
|
+
_globals['_RPCREQUEST']._serialized_end=453
|
|
43
|
+
_globals['_RPCRESPONSE']._serialized_start=455
|
|
44
|
+
_globals['_RPCRESPONSE']._serialized_end=560
|
|
45
|
+
_globals['_HEARTBEAT']._serialized_start=562
|
|
46
|
+
_globals['_HEARTBEAT']._serialized_end=590
|
|
47
|
+
_globals['_CANCEL']._serialized_start=592
|
|
48
|
+
_globals['_CANCEL']._serialized_end=616
|
|
49
|
+
_globals['_HOSTFRAME']._serialized_start=619
|
|
50
|
+
_globals['_HOSTFRAME']._serialized_end=898
|
|
51
|
+
_globals['_HOSTTUNNEL']._serialized_start=900
|
|
52
|
+
_globals['_HOSTTUNNEL']._serialized_end=969
|
|
53
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
|
2
|
+
"""Client and server classes corresponding to protobuf-defined services."""
|
|
3
|
+
import grpc
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
import grpc_host_pb2 as grpc__host__pb2
|
|
7
|
+
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.78.0'
|
|
9
|
+
GRPC_VERSION = grpc.__version__
|
|
10
|
+
_version_not_supported = False
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from grpc._utilities import first_version_is_lower
|
|
14
|
+
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
|
|
15
|
+
except ImportError:
|
|
16
|
+
_version_not_supported = True
|
|
17
|
+
|
|
18
|
+
if _version_not_supported:
|
|
19
|
+
raise RuntimeError(
|
|
20
|
+
f'The grpc package installed is at version {GRPC_VERSION},'
|
|
21
|
+
+ ' but the generated code in grpc_host_pb2_grpc.py depends on'
|
|
22
|
+
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
|
|
23
|
+
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
|
|
24
|
+
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class HostTunnelStub(object):
|
|
29
|
+
"""Missing associated documentation comment in .proto file."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, channel):
|
|
32
|
+
"""Constructor.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
channel: A grpc.Channel.
|
|
36
|
+
"""
|
|
37
|
+
self.Connect = channel.stream_stream(
|
|
38
|
+
'/remoterf.HostTunnel/Connect',
|
|
39
|
+
request_serializer=grpc__host__pb2.HostFrame.SerializeToString,
|
|
40
|
+
response_deserializer=grpc__host__pb2.HostFrame.FromString,
|
|
41
|
+
_registered_method=True)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class HostTunnelServicer(object):
|
|
45
|
+
"""Missing associated documentation comment in .proto file."""
|
|
46
|
+
|
|
47
|
+
def Connect(self, request_iterator, context):
|
|
48
|
+
"""Missing associated documentation comment in .proto file."""
|
|
49
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
50
|
+
context.set_details('Method not implemented!')
|
|
51
|
+
raise NotImplementedError('Method not implemented!')
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def add_HostTunnelServicer_to_server(servicer, server):
|
|
55
|
+
rpc_method_handlers = {
|
|
56
|
+
'Connect': grpc.stream_stream_rpc_method_handler(
|
|
57
|
+
servicer.Connect,
|
|
58
|
+
request_deserializer=grpc__host__pb2.HostFrame.FromString,
|
|
59
|
+
response_serializer=grpc__host__pb2.HostFrame.SerializeToString,
|
|
60
|
+
),
|
|
61
|
+
}
|
|
62
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
|
63
|
+
'remoterf.HostTunnel', rpc_method_handlers)
|
|
64
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
|
65
|
+
server.add_registered_method_handlers('remoterf.HostTunnel', rpc_method_handlers)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# This class is part of an EXPERIMENTAL API.
|
|
69
|
+
class HostTunnel(object):
|
|
70
|
+
"""Missing associated documentation comment in .proto file."""
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def Connect(request_iterator,
|
|
74
|
+
target,
|
|
75
|
+
options=(),
|
|
76
|
+
channel_credentials=None,
|
|
77
|
+
call_credentials=None,
|
|
78
|
+
insecure=False,
|
|
79
|
+
compression=None,
|
|
80
|
+
wait_for_ready=None,
|
|
81
|
+
timeout=None,
|
|
82
|
+
metadata=None):
|
|
83
|
+
return grpc.experimental.stream_stream(
|
|
84
|
+
request_iterator,
|
|
85
|
+
target,
|
|
86
|
+
'/remoterf.HostTunnel/Connect',
|
|
87
|
+
grpc__host__pb2.HostFrame.SerializeToString,
|
|
88
|
+
grpc__host__pb2.HostFrame.FromString,
|
|
89
|
+
options,
|
|
90
|
+
channel_credentials,
|
|
91
|
+
insecure,
|
|
92
|
+
call_credentials,
|
|
93
|
+
compression,
|
|
94
|
+
wait_for_ready,
|
|
95
|
+
timeout,
|
|
96
|
+
metadata,
|
|
97
|
+
_registered_method=True)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: grpc.proto
|
|
5
|
+
# Protobuf Python Version: 5.29.0
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
5,
|
|
15
|
+
29,
|
|
16
|
+
0,
|
|
17
|
+
'',
|
|
18
|
+
'grpc.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ngrpc.proto\x12\tremote_rf\"\xa2\x01\n\x11GenericRPCRequest\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x34\n\x04\x61rgs\x18\x02 \x03(\x0b\x32&.remote_rf.GenericRPCRequest.ArgsEntry\x1a@\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.remote_rf.Argument:\x02\x38\x01\"\x96\x01\n\x12GenericRPCResponse\x12;\n\x07results\x18\x01 \x03(\x0b\x32*.remote_rf.GenericRPCResponse.ResultsEntry\x1a\x43\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.remote_rf.Argument:\x02\x38\x01\"\x19\n\nArrayShape\x12\x0b\n\x03\x64im\x18\x01 \x03(\x05\"+\n\rComplexNumber\x12\x0c\n\x04real\x18\x01 \x01(\x02\x12\x0c\n\x04imag\x18\x02 \x01(\x02\"a\n\x11\x43omplexNumpyArray\x12$\n\x05shape\x18\x01 \x01(\x0b\x32\x15.remote_rf.ArrayShape\x12&\n\x04\x64\x61ta\x18\x02 \x03(\x0b\x32\x18.remote_rf.ComplexNumber\"D\n\x0eRealNumpyArray\x12$\n\x05shape\x18\x01 \x01(\x0b\x32\x15.remote_rf.ArrayShape\x12\x0c\n\x04\x64\x61ta\x18\x02 \x03(\x02\"\xd7\x01\n\x08\x41rgument\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x15\n\x0bint64_value\x18\x02 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x03 \x01(\x02H\x00\x12\x14\n\nbool_value\x18\x04 \x01(\x08H\x00\x12\x35\n\rcomplex_array\x18\x05 \x01(\x0b\x32\x1c.remote_rf.ComplexNumpyArrayH\x00\x12/\n\nreal_array\x18\x06 \x01(\x0b\x32\x19.remote_rf.RealNumpyArrayH\x00\x42\x07\n\x05value2Q\n\nGenericRPC\x12\x43\n\x04\x43\x61ll\x12\x1c.remote_rf.GenericRPCRequest\x1a\x1d.remote_rf.GenericRPCResponseB\x1e\n\x10\x63om.example.demoB\nDemoProtosb\x06proto3')
|
|
28
|
+
|
|
29
|
+
_globals = globals()
|
|
30
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'grpc_pb2', _globals)
|
|
32
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
34
|
+
_globals['DESCRIPTOR']._serialized_options = b'\n\020com.example.demoB\nDemoProtos'
|
|
35
|
+
_globals['_GENERICRPCREQUEST_ARGSENTRY']._loaded_options = None
|
|
36
|
+
_globals['_GENERICRPCREQUEST_ARGSENTRY']._serialized_options = b'8\001'
|
|
37
|
+
_globals['_GENERICRPCRESPONSE_RESULTSENTRY']._loaded_options = None
|
|
38
|
+
_globals['_GENERICRPCRESPONSE_RESULTSENTRY']._serialized_options = b'8\001'
|
|
39
|
+
_globals['_GENERICRPCREQUEST']._serialized_start=26
|
|
40
|
+
_globals['_GENERICRPCREQUEST']._serialized_end=188
|
|
41
|
+
_globals['_GENERICRPCREQUEST_ARGSENTRY']._serialized_start=124
|
|
42
|
+
_globals['_GENERICRPCREQUEST_ARGSENTRY']._serialized_end=188
|
|
43
|
+
_globals['_GENERICRPCRESPONSE']._serialized_start=191
|
|
44
|
+
_globals['_GENERICRPCRESPONSE']._serialized_end=341
|
|
45
|
+
_globals['_GENERICRPCRESPONSE_RESULTSENTRY']._serialized_start=274
|
|
46
|
+
_globals['_GENERICRPCRESPONSE_RESULTSENTRY']._serialized_end=341
|
|
47
|
+
_globals['_ARRAYSHAPE']._serialized_start=343
|
|
48
|
+
_globals['_ARRAYSHAPE']._serialized_end=368
|
|
49
|
+
_globals['_COMPLEXNUMBER']._serialized_start=370
|
|
50
|
+
_globals['_COMPLEXNUMBER']._serialized_end=413
|
|
51
|
+
_globals['_COMPLEXNUMPYARRAY']._serialized_start=415
|
|
52
|
+
_globals['_COMPLEXNUMPYARRAY']._serialized_end=512
|
|
53
|
+
_globals['_REALNUMPYARRAY']._serialized_start=514
|
|
54
|
+
_globals['_REALNUMPYARRAY']._serialized_end=582
|
|
55
|
+
_globals['_ARGUMENT']._serialized_start=585
|
|
56
|
+
_globals['_ARGUMENT']._serialized_end=800
|
|
57
|
+
_globals['_GENERICRPC']._serialized_start=802
|
|
58
|
+
_globals['_GENERICRPC']._serialized_end=883
|
|
59
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
|
2
|
+
"""Client and server classes corresponding to protobuf-defined services."""
|
|
3
|
+
import grpc
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
from . import grpc_pb2 as grpc__pb2
|
|
7
|
+
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.71.0'
|
|
9
|
+
GRPC_VERSION = grpc.__version__
|
|
10
|
+
_version_not_supported = False
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from grpc._utilities import first_version_is_lower
|
|
14
|
+
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
|
|
15
|
+
except ImportError:
|
|
16
|
+
_version_not_supported = True
|
|
17
|
+
|
|
18
|
+
if _version_not_supported:
|
|
19
|
+
raise RuntimeError(
|
|
20
|
+
f'The grpc package installed is at version {GRPC_VERSION},'
|
|
21
|
+
+ f' but the generated code in grpc_pb2_grpc.py depends on'
|
|
22
|
+
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
|
|
23
|
+
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
|
|
24
|
+
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class GenericRPCStub(object):
|
|
29
|
+
"""Missing associated documentation comment in .proto file."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, channel):
|
|
32
|
+
"""Constructor.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
channel: A grpc.Channel.
|
|
36
|
+
"""
|
|
37
|
+
self.Call = channel.unary_unary(
|
|
38
|
+
'/remote_rf.GenericRPC/Call',
|
|
39
|
+
request_serializer=grpc__pb2.GenericRPCRequest.SerializeToString,
|
|
40
|
+
response_deserializer=grpc__pb2.GenericRPCResponse.FromString,
|
|
41
|
+
_registered_method=True)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class GenericRPCServicer(object):
|
|
45
|
+
"""Missing associated documentation comment in .proto file."""
|
|
46
|
+
|
|
47
|
+
def Call(self, request, context):
|
|
48
|
+
"""Missing associated documentation comment in .proto file."""
|
|
49
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
50
|
+
context.set_details('Method not implemented!')
|
|
51
|
+
raise NotImplementedError('Method not implemented!')
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def add_GenericRPCServicer_to_server(servicer, server):
|
|
55
|
+
rpc_method_handlers = {
|
|
56
|
+
'Call': grpc.unary_unary_rpc_method_handler(
|
|
57
|
+
servicer.Call,
|
|
58
|
+
request_deserializer=grpc__pb2.GenericRPCRequest.FromString,
|
|
59
|
+
response_serializer=grpc__pb2.GenericRPCResponse.SerializeToString,
|
|
60
|
+
),
|
|
61
|
+
}
|
|
62
|
+
generic_handler = grpc.method_handlers_generic_handler(
|
|
63
|
+
'remote_rf.GenericRPC', rpc_method_handlers)
|
|
64
|
+
server.add_generic_rpc_handlers((generic_handler,))
|
|
65
|
+
server.add_registered_method_handlers('remote_rf.GenericRPC', rpc_method_handlers)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# This class is part of an EXPERIMENTAL API.
|
|
69
|
+
class GenericRPC(object):
|
|
70
|
+
"""Missing associated documentation comment in .proto file."""
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def Call(request,
|
|
74
|
+
target,
|
|
75
|
+
options=(),
|
|
76
|
+
channel_credentials=None,
|
|
77
|
+
call_credentials=None,
|
|
78
|
+
insecure=False,
|
|
79
|
+
compression=None,
|
|
80
|
+
wait_for_ready=None,
|
|
81
|
+
timeout=None,
|
|
82
|
+
metadata=None):
|
|
83
|
+
return grpc.experimental.unary_unary(
|
|
84
|
+
request,
|
|
85
|
+
target,
|
|
86
|
+
'/remote_rf.GenericRPC/Call',
|
|
87
|
+
grpc__pb2.GenericRPCRequest.SerializeToString,
|
|
88
|
+
grpc__pb2.GenericRPCResponse.FromString,
|
|
89
|
+
options,
|
|
90
|
+
channel_credentials,
|
|
91
|
+
insecure,
|
|
92
|
+
call_credentials,
|
|
93
|
+
compression,
|
|
94
|
+
wait_for_ready,
|
|
95
|
+
timeout,
|
|
96
|
+
metadata,
|
|
97
|
+
_registered_method=True)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from prompt_toolkit.styles import Style
|
|
2
|
+
from prompt_toolkit.formatted_text import FormattedText
|
|
3
|
+
from prompt_toolkit import print_formatted_text
|
|
4
|
+
from enum import Enum
|
|
5
|
+
|
|
6
|
+
class Sty(Enum):
|
|
7
|
+
# Basic colors
|
|
8
|
+
RED = 'red'
|
|
9
|
+
GREEN = 'green'
|
|
10
|
+
BLUE = 'blue'
|
|
11
|
+
YELLOW = 'yellow'
|
|
12
|
+
MAGENTA = 'magenta'
|
|
13
|
+
CYAN = 'cyan'
|
|
14
|
+
GRAY = 'gray'
|
|
15
|
+
|
|
16
|
+
# Background colors
|
|
17
|
+
BG_RED = 'bg-red'
|
|
18
|
+
BG_GREEN = 'bg-green'
|
|
19
|
+
BG_BLUE = 'bg-blue'
|
|
20
|
+
|
|
21
|
+
# Bright versions
|
|
22
|
+
BRIGHT_RED = 'bright-red'
|
|
23
|
+
BRIGHT_GREEN = 'bright-green'
|
|
24
|
+
BRIGHT_BLUE = 'bright-blue'
|
|
25
|
+
|
|
26
|
+
# Formatting
|
|
27
|
+
BOLD = 'bold'
|
|
28
|
+
ITALIC = 'italic'
|
|
29
|
+
UNDERLINE = 'underline'
|
|
30
|
+
BLINK = 'blink'
|
|
31
|
+
REVERSE = 'reverse'
|
|
32
|
+
|
|
33
|
+
# Combinations
|
|
34
|
+
ERROR = 'error'
|
|
35
|
+
WARNING = 'warning'
|
|
36
|
+
INFO = 'info'
|
|
37
|
+
|
|
38
|
+
# Special
|
|
39
|
+
SELECTED = 'selected'
|
|
40
|
+
DEFAULT = 'default'
|
|
41
|
+
|
|
42
|
+
# Define the styles based on ANSI codes
|
|
43
|
+
style = Style.from_dict({
|
|
44
|
+
# Basic colors
|
|
45
|
+
'red': 'fg:#110000',
|
|
46
|
+
'green': 'fg:#003300',
|
|
47
|
+
'blue': 'fg:#0000ff',
|
|
48
|
+
'yellow': 'fg:#ffff00',
|
|
49
|
+
'magenta': 'fg:#ff00ff',
|
|
50
|
+
'cyan': 'fg:#00ffff',
|
|
51
|
+
'gray': 'fg:#808080',
|
|
52
|
+
|
|
53
|
+
# Bright versions
|
|
54
|
+
'bright-red': 'fg:#ff5555',
|
|
55
|
+
'bright-green': 'fg:#00ff00',
|
|
56
|
+
'bright-blue': 'fg:#5555ff',
|
|
57
|
+
|
|
58
|
+
# Formatting
|
|
59
|
+
'bold': 'bold',
|
|
60
|
+
'italic': 'italic',
|
|
61
|
+
'underline': 'underline',
|
|
62
|
+
'reverse': 'reverse',
|
|
63
|
+
|
|
64
|
+
# Combinations
|
|
65
|
+
'error': 'bg:#ff0000 fg:#ffffff bold',
|
|
66
|
+
'warning': 'bg:#ffff00 fg:#000000 bold',
|
|
67
|
+
'info': 'bg:#0000ff fg:#ffffff italic underline',
|
|
68
|
+
|
|
69
|
+
# Special
|
|
70
|
+
'selected': 'bg:#ffffff #000000 reverse',
|
|
71
|
+
'default':''
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
def printf(*args) -> str:
|
|
75
|
+
if len(args) % 2 != 0:
|
|
76
|
+
raise ValueError('Arguments must be in pairs of two.')
|
|
77
|
+
|
|
78
|
+
# Create formatted text using the defined style
|
|
79
|
+
formatted_text = []
|
|
80
|
+
|
|
81
|
+
for i in range(0, len(args), 2):
|
|
82
|
+
message = args[i]
|
|
83
|
+
styles = args[i+1]
|
|
84
|
+
|
|
85
|
+
if not isinstance(styles, tuple):
|
|
86
|
+
styles = (styles,)
|
|
87
|
+
|
|
88
|
+
resolved_styles = (s.value if isinstance(s, Enum) else s for s in styles)
|
|
89
|
+
|
|
90
|
+
style_class = ' '.join(resolved_styles)
|
|
91
|
+
|
|
92
|
+
formatted_text.append(('class:' + style_class, message))
|
|
93
|
+
|
|
94
|
+
# Create FormattedText object from pairs
|
|
95
|
+
text = FormattedText(formatted_text)
|
|
96
|
+
|
|
97
|
+
print_formatted_text(text, style=style)
|
|
98
|
+
return text
|
|
99
|
+
|
|
100
|
+
def stylize(*args):
|
|
101
|
+
"""
|
|
102
|
+
Create a styled prompt text based on pairs of (text, (Sty, ...), ...).
|
|
103
|
+
"""
|
|
104
|
+
if len(args) % 2 != 0:
|
|
105
|
+
raise ValueError("Arguments must be in pairs of (text, style_class).")
|
|
106
|
+
|
|
107
|
+
styled_parts = []
|
|
108
|
+
for i in range(0, len(args), 2):
|
|
109
|
+
text = args[i]
|
|
110
|
+
styles = args[i + 1]
|
|
111
|
+
|
|
112
|
+
if not isinstance(styles, tuple):
|
|
113
|
+
styles = (styles,)
|
|
114
|
+
|
|
115
|
+
resolved_styles = (s.value if isinstance(s, Enum) else s for s in styles)
|
|
116
|
+
|
|
117
|
+
style_class = ' '.join(resolved_styles)
|
|
118
|
+
styled_parts.append(('class:' + style_class, text))
|
|
119
|
+
|
|
120
|
+
return FormattedText(styled_parts)
|