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.
Files changed (40) hide show
  1. remoterf_server-0.1.0/PKG-INFO +9 -0
  2. remoterf_server-0.1.0/README.md +171 -0
  3. remoterf_server-0.1.0/pyproject.toml +27 -0
  4. remoterf_server-0.1.0/setup.cfg +4 -0
  5. remoterf_server-0.1.0/src/remoteRF_server/__init__.py +0 -0
  6. remoterf_server-0.1.0/src/remoteRF_server/common/__init__.py +0 -0
  7. remoterf_server-0.1.0/src/remoteRF_server/common/grpc/__init__.py +1 -0
  8. remoterf_server-0.1.0/src/remoteRF_server/common/grpc/grpc_host_pb2.py +53 -0
  9. remoterf_server-0.1.0/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +97 -0
  10. remoterf_server-0.1.0/src/remoteRF_server/common/grpc/grpc_pb2.py +59 -0
  11. remoterf_server-0.1.0/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +97 -0
  12. remoterf_server-0.1.0/src/remoteRF_server/common/utils/__init__.py +5 -0
  13. remoterf_server-0.1.0/src/remoteRF_server/common/utils/ansi_codes.py +120 -0
  14. remoterf_server-0.1.0/src/remoteRF_server/common/utils/api_token.py +31 -0
  15. remoterf_server-0.1.0/src/remoteRF_server/common/utils/db_connection.py +51 -0
  16. remoterf_server-0.1.0/src/remoteRF_server/common/utils/list_string.py +5 -0
  17. remoterf_server-0.1.0/src/remoteRF_server/common/utils/process_arg.py +80 -0
  18. remoterf_server-0.1.0/src/remoteRF_server/drivers/__init__.py +0 -0
  19. remoterf_server-0.1.0/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
  20. remoterf_server-0.1.0/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +121 -0
  21. remoterf_server-0.1.0/src/remoteRF_server/host/__init__.py +0 -0
  22. remoterf_server-0.1.0/src/remoteRF_server/host/host_directory_store.py +160 -0
  23. remoterf_server-0.1.0/src/remoteRF_server/host/host_tunnel_server.py +828 -0
  24. remoterf_server-0.1.0/src/remoteRF_server/server/__init__.py +0 -0
  25. remoterf_server-0.1.0/src/remoteRF_server/server/acc_perms.py +315 -0
  26. remoterf_server-0.1.0/src/remoteRF_server/server/cert_provider.py +242 -0
  27. remoterf_server-0.1.0/src/remoteRF_server/server/device_manager.py +235 -0
  28. remoterf_server-0.1.0/src/remoteRF_server/server/grpc_server.py +749 -0
  29. remoterf_server-0.1.0/src/remoteRF_server/server/reservation.py +596 -0
  30. remoterf_server-0.1.0/src/remoteRF_server/server/rpc_manager.py +38 -0
  31. remoterf_server-0.1.0/src/remoteRF_server/server/user_group_cli.py +589 -0
  32. remoterf_server-0.1.0/src/remoteRF_server/server/user_group_handler.py +1113 -0
  33. remoterf_server-0.1.0/src/remoteRF_server/tools/__init__.py +191 -0
  34. remoterf_server-0.1.0/src/remoteRF_server/tools/cert_gen.py +190 -0
  35. remoterf_server-0.1.0/src/remoteRF_server.egg-info/PKG-INFO +9 -0
  36. remoterf_server-0.1.0/src/remoteRF_server.egg-info/SOURCES.txt +38 -0
  37. remoterf_server-0.1.0/src/remoteRF_server.egg-info/dependency_links.txt +1 -0
  38. remoterf_server-0.1.0/src/remoteRF_server.egg-info/entry_points.txt +3 -0
  39. remoterf_server-0.1.0/src/remoteRF_server.egg-info/requires.txt +6 -0
  40. remoterf_server-0.1.0/src/remoteRF_server.egg-info/top_level.txt +1 -0
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: remoteRF-server
3
+ Version: 0.1.0
4
+ Requires-Dist: grpcio
5
+ Requires-Dist: protobuf
6
+ Requires-Dist: numpy
7
+ Requires-Dist: prompt_toolkit
8
+ Requires-Dist: python-dotenv
9
+ Requires-Dist: grpcio-tools
@@ -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"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
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,5 @@
1
+ from .api_token import validate_token, generate_token, hash_token
2
+ from .process_arg import unmap_arg, map_arg
3
+ from .ansi_codes import printf, stylize, Sty
4
+ from .list_string import list_to_str, str_to_list
5
+ from .db_connection import db_connection
@@ -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)