remoterf 0.0.7.27__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.

Potentially problematic release.


This version of remoterf might be problematic. Click here for more details.

Files changed (37) hide show
  1. remoterf-0.0.7.27/LICENSE +21 -0
  2. remoterf-0.0.7.27/MANIFEST.in +2 -0
  3. remoterf-0.0.7.27/PKG-INFO +150 -0
  4. remoterf-0.0.7.27/README.md +133 -0
  5. remoterf-0.0.7.27/setup.cfg +4 -0
  6. remoterf-0.0.7.27/setup.py +33 -0
  7. remoterf-0.0.7.27/src/remoteRF/__init__.py +0 -0
  8. remoterf-0.0.7.27/src/remoteRF/common/__init__.py +2 -0
  9. remoterf-0.0.7.27/src/remoteRF/common/grpc/__init__.py +1 -0
  10. remoterf-0.0.7.27/src/remoteRF/common/grpc/grpc_pb2.py +59 -0
  11. remoterf-0.0.7.27/src/remoteRF/common/grpc/grpc_pb2_grpc.py +97 -0
  12. remoterf-0.0.7.27/src/remoteRF/common/utils/__init__.py +4 -0
  13. remoterf-0.0.7.27/src/remoteRF/common/utils/ansi_codes.py +120 -0
  14. remoterf-0.0.7.27/src/remoteRF/common/utils/api_token.py +31 -0
  15. remoterf-0.0.7.27/src/remoteRF/common/utils/list_string.py +5 -0
  16. remoterf-0.0.7.27/src/remoteRF/common/utils/process_arg.py +80 -0
  17. remoterf-0.0.7.27/src/remoteRF/core/__init__.py +2 -0
  18. remoterf-0.0.7.27/src/remoteRF/core/acc_login.py +4 -0
  19. remoterf-0.0.7.27/src/remoteRF/core/app.py +481 -0
  20. remoterf-0.0.7.27/src/remoteRF/core/certs/__init__.py +0 -0
  21. remoterf-0.0.7.27/src/remoteRF/core/certs/ca.crt +32 -0
  22. remoterf-0.0.7.27/src/remoteRF/core/certs/ca.key +52 -0
  23. remoterf-0.0.7.27/src/remoteRF/core/certs/cert.pem +19 -0
  24. remoterf-0.0.7.27/src/remoteRF/core/certs/key.pem +28 -0
  25. remoterf-0.0.7.27/src/remoteRF/core/certs/server.crt +19 -0
  26. remoterf-0.0.7.27/src/remoteRF/core/certs/server.key +28 -0
  27. remoterf-0.0.7.27/src/remoteRF/core/grpc_acc.py +52 -0
  28. remoterf-0.0.7.27/src/remoteRF/core/grpc_client.py +97 -0
  29. remoterf-0.0.7.27/src/remoteRF/drivers/__init__.py +0 -0
  30. remoterf-0.0.7.27/src/remoteRF/drivers/adalm_pluto/__init__.py +1 -0
  31. remoterf-0.0.7.27/src/remoteRF/drivers/adalm_pluto/pluto_remote.py +250 -0
  32. remoterf-0.0.7.27/src/remoteRF.egg-info/PKG-INFO +150 -0
  33. remoterf-0.0.7.27/src/remoteRF.egg-info/SOURCES.txt +41 -0
  34. remoterf-0.0.7.27/src/remoteRF.egg-info/dependency_links.txt +1 -0
  35. remoterf-0.0.7.27/src/remoteRF.egg-info/entry_points.txt +2 -0
  36. remoterf-0.0.7.27/src/remoteRF.egg-info/requires.txt +5 -0
  37. remoterf-0.0.7.27/src/remoteRF.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Ethan Ge
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ # Include all .crt, .key, and .pem files
2
+ recursive-include src/remoteRF *.crt *.key *.pem
@@ -0,0 +1,150 @@
1
+ Metadata-Version: 2.1
2
+ Name: remoterf
3
+ Version: 0.0.7.27
4
+ Summary: A python API to remotely access signal centric hardware. Client-side only!
5
+ Author: Ethan Ge
6
+ Author-email: ethoGalaxy@gmail.com
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: grpcio==1.71.0
13
+ Requires-Dist: protobuf
14
+ Requires-Dist: numpy
15
+ Requires-Dist: prompt_toolkit
16
+ Requires-Dist: python-dotenv
17
+
18
+ # Remote RF
19
+
20
+ A python API to remotely access signal centric hardware.
21
+
22
+ Courtesy of Wireless Lab @ UCLA. - Ethan Ge
23
+
24
+ ## Prerequisites
25
+
26
+ - **Python 3.10**: This package works in Python 3.10+. If you don’t have Python installed, you can download it from the [official Python website](https://www.python.org/downloads/).
27
+
28
+ To check your current Python version, open a terminal and run:
29
+
30
+ ```bash
31
+ python --version
32
+ ```
33
+
34
+ - **UCLA VPN**: Please ensure that you are connected to the UCLA VPN. You can download and configure the VPN client from the following link: [UCLA VPN Client Download](https://www.it.ucla.edu/it-support-center/services/virtual-private-network-vpn-clients). If you’re not connected to the VPN, you will not have access to the lab servers.
35
+
36
+ ## Installation
37
+
38
+ 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).
39
+
40
+ ```bash
41
+ python3 -m venv venv # Create virtual environment
42
+ source venv/bin/activate # Activate virtual environment
43
+
44
+ pip install remoteRF # Install remoteRF
45
+ ```
46
+
47
+ If `pip install` doesn't work, you can clone the [source](https://github.com/WirelessLabAtUCLA/RemoteRF-Client) directly from github.
48
+
49
+ <!-- 1. **Clone the repository:**
50
+ ```bash
51
+ git clone https://github.com/WirelessLabAtUCLA/RemoteRF-Client
52
+ cd repository-name
53
+ ```
54
+ 2. **Install the package using** `pip` **in editable mode:**
55
+ ```bash
56
+ pip install -e .
57
+ ```
58
+ This command installs the package in "editable" mode, allowing for modifications to the local code without reinstalling. For more details on installing packages from local directories, refer to Python Packaging: [Installing from Local Archives](https://packaging.python.org/en/latest/tutorials/installing-packages/#installing-packages-from-local-archives). -->
59
+
60
+ ## Reservation
61
+
62
+ Usage of the platform requires you to register a account and reserve a device in order to run scripts remotely.
63
+
64
+ ### 1. **Start UCLA VPN**
65
+
66
+ - Start the CISCO Secure client, login and connect to any of the options.
67
+
68
+ ### 2. **Register a account**:
69
+ ```bash
70
+ remoterf-login
71
+ # Run in the terminal
72
+ # where the Python library is installed
73
+
74
+ # Typically, this will be the terminal where you’ve activated the virtual environment if you’re using one
75
+ ```
76
+
77
+ - Input `r` to register a account, or `l` to login to a existing one.
78
+
79
+ <!-- 2. **You will be prompted with this**: -->
80
+ ```bash
81
+ Welcome to Remote RF Account System.
82
+ Please login or register to continue. (l/r):
83
+ ```
84
+
85
+ - Once in, input `help` to see all avaliable commands.
86
+
87
+ ### 3. **Reserve Device**:
88
+ ```bash
89
+ getdev # To view all avaliable devices
90
+
91
+ # Note the device ID. You will need this later to reserve said device
92
+ ```
93
+
94
+ ```bash
95
+ getres # To view times not avaliable
96
+
97
+ # Optionally, you can also view all reservations, and determine a time slot you want a specific device reserved
98
+ ```
99
+ ```bash
100
+ perms # To view your permissions
101
+
102
+ # Depending on your permission levels, you will be given different restrictions
103
+ ```
104
+
105
+ ```bash
106
+ resdev # To reserve a device
107
+
108
+ # Input the number of days you want to view, and it will display available reservations in that time span.
109
+
110
+ Reservation successful. Thy Token -> example_token
111
+
112
+ # Take note of this token. You will need it to actually access the device.
113
+ ```
114
+
115
+ ## Remote Access
116
+
117
+ With this token, you can now run scripts remotely. Please keep in mind that you MUST be connected to the UCLA VPN for this to work.
118
+ Here is a explained sample script to get you going!
119
+
120
+ #### Python Script:
121
+
122
+ ```python
123
+ from remoteRF.drivers.adalm_pluto import * # Imports device Pluto SDR remote drivers. Change depending on desired device.
124
+
125
+ sdr = adi.Pluto( # Device initialization.
126
+ token = 'example_token' # Place the prior token here.
127
+ )
128
+
129
+ # You can now use this 'sdr' as you normally would with the default Pluto drivers.
130
+ ```
131
+
132
+ If converting a existing `non-remoteRF` compatible script:
133
+
134
+ ```diff
135
+ - import existing_device_drivers
136
+
137
+ + from remoteRF.drivers.device_drivers import *
138
+
139
+ - device = device(init)
140
+
141
+ + device = device(token = 'sample_token')
142
+ ```
143
+
144
+ Nothing else needs changing!
145
+
146
+ ## Closing
147
+
148
+ This is fundamentally a experimental platform, and there will be many unknown bugs and issues. Some devices do not have universal support for all its functions at the moment, I am working on that aspect.
149
+
150
+ **So please submit feedback!**
@@ -0,0 +1,133 @@
1
+ # Remote RF
2
+
3
+ A python API to remotely access signal centric hardware.
4
+
5
+ Courtesy of Wireless Lab @ UCLA. - Ethan Ge
6
+
7
+ ## Prerequisites
8
+
9
+ - **Python 3.10**: This package works in Python 3.10+. If you don’t have Python installed, you can download it from the [official Python website](https://www.python.org/downloads/).
10
+
11
+ To check your current Python version, open a terminal and run:
12
+
13
+ ```bash
14
+ python --version
15
+ ```
16
+
17
+ - **UCLA VPN**: Please ensure that you are connected to the UCLA VPN. You can download and configure the VPN client from the following link: [UCLA VPN Client Download](https://www.it.ucla.edu/it-support-center/services/virtual-private-network-vpn-clients). If you’re not connected to the VPN, you will not have access to the lab servers.
18
+
19
+ ## Installation
20
+
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
+
23
+ ```bash
24
+ python3 -m venv venv # Create virtual environment
25
+ source venv/bin/activate # Activate virtual environment
26
+
27
+ pip install remoteRF # Install remoteRF
28
+ ```
29
+
30
+ If `pip install` doesn't work, you can clone the [source](https://github.com/WirelessLabAtUCLA/RemoteRF-Client) directly from github.
31
+
32
+ <!-- 1. **Clone the repository:**
33
+ ```bash
34
+ git clone https://github.com/WirelessLabAtUCLA/RemoteRF-Client
35
+ cd repository-name
36
+ ```
37
+ 2. **Install the package using** `pip` **in editable mode:**
38
+ ```bash
39
+ pip install -e .
40
+ ```
41
+ This command installs the package in "editable" mode, allowing for modifications to the local code without reinstalling. For more details on installing packages from local directories, refer to Python Packaging: [Installing from Local Archives](https://packaging.python.org/en/latest/tutorials/installing-packages/#installing-packages-from-local-archives). -->
42
+
43
+ ## Reservation
44
+
45
+ Usage of the platform requires you to register a account and reserve a device in order to run scripts remotely.
46
+
47
+ ### 1. **Start UCLA VPN**
48
+
49
+ - Start the CISCO Secure client, login and connect to any of the options.
50
+
51
+ ### 2. **Register a account**:
52
+ ```bash
53
+ remoterf-login
54
+ # Run in the terminal
55
+ # where the Python library is installed
56
+
57
+ # Typically, this will be the terminal where you’ve activated the virtual environment if you’re using one
58
+ ```
59
+
60
+ - Input `r` to register a account, or `l` to login to a existing one.
61
+
62
+ <!-- 2. **You will be prompted with this**: -->
63
+ ```bash
64
+ Welcome to Remote RF Account System.
65
+ Please login or register to continue. (l/r):
66
+ ```
67
+
68
+ - Once in, input `help` to see all avaliable commands.
69
+
70
+ ### 3. **Reserve Device**:
71
+ ```bash
72
+ getdev # To view all avaliable devices
73
+
74
+ # Note the device ID. You will need this later to reserve said device
75
+ ```
76
+
77
+ ```bash
78
+ getres # To view times not avaliable
79
+
80
+ # Optionally, you can also view all reservations, and determine a time slot you want a specific device reserved
81
+ ```
82
+ ```bash
83
+ perms # To view your permissions
84
+
85
+ # Depending on your permission levels, you will be given different restrictions
86
+ ```
87
+
88
+ ```bash
89
+ resdev # To reserve a device
90
+
91
+ # Input the number of days you want to view, and it will display available reservations in that time span.
92
+
93
+ Reservation successful. Thy Token -> example_token
94
+
95
+ # Take note of this token. You will need it to actually access the device.
96
+ ```
97
+
98
+ ## Remote Access
99
+
100
+ With this token, you can now run scripts remotely. Please keep in mind that you MUST be connected to the UCLA VPN for this to work.
101
+ Here is a explained sample script to get you going!
102
+
103
+ #### Python Script:
104
+
105
+ ```python
106
+ from remoteRF.drivers.adalm_pluto import * # Imports device Pluto SDR remote drivers. Change depending on desired device.
107
+
108
+ sdr = adi.Pluto( # Device initialization.
109
+ token = 'example_token' # Place the prior token here.
110
+ )
111
+
112
+ # You can now use this 'sdr' as you normally would with the default Pluto drivers.
113
+ ```
114
+
115
+ If converting a existing `non-remoteRF` compatible script:
116
+
117
+ ```diff
118
+ - import existing_device_drivers
119
+
120
+ + from remoteRF.drivers.device_drivers import *
121
+
122
+ - device = device(init)
123
+
124
+ + device = device(token = 'sample_token')
125
+ ```
126
+
127
+ Nothing else needs changing!
128
+
129
+ ## Closing
130
+
131
+ This is fundamentally a experimental platform, and there will be many unknown bugs and issues. Some devices do not have universal support for all its functions at the moment, I am working on that aspect.
132
+
133
+ **So please submit feedback!**
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,33 @@
1
+ from setuptools import setup, find_packages
2
+ import os
3
+
4
+ with open("README.md", "r", encoding="utf-8") as fh:
5
+ long_description = fh.read()
6
+
7
+ setup(
8
+ name="remoterf",
9
+ version="0.0.7.27",
10
+ author="Ethan Ge",
11
+ author_email="ethoGalaxy@gmail.com",
12
+ description="A python API to remotely access signal centric hardware. Client-side only!",
13
+ long_description=long_description, # Set the README content here
14
+ long_description_content_type="text/markdown", # Specify that it's Markdown
15
+ packages=find_packages(where="src"), # Automatically finds subpackages like core, deviceA, deviceB
16
+ package_dir={"": "src"},
17
+ license_file='MIT',
18
+ include_package_data=True, # Includes files specified in MANIFEST.in
19
+ install_requires=[
20
+ "grpcio==1.71.0", "protobuf", "numpy", "prompt_toolkit", "python-dotenv"
21
+ ],
22
+ classifiers=[
23
+ "Programming Language :: Python :: 3",
24
+ "License :: OSI Approved :: MIT License",
25
+ "Operating System :: OS Independent",
26
+ ],
27
+ python_requires='>=3.10',
28
+ entry_points={
29
+ 'console_scripts': [
30
+ 'remoterf-login=remoteRF.core.acc_login:main',
31
+ ],
32
+ },
33
+ )
File without changes
@@ -0,0 +1,2 @@
1
+ from .grpc import *
2
+ from .utils import *
@@ -0,0 +1 @@
1
+ from . import grpc_pb2, grpc_pb2_grpc
@@ -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,4 @@
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
@@ -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)
@@ -0,0 +1,31 @@
1
+ import os
2
+ import hashlib
3
+ import base64
4
+ import secrets
5
+ from dotenv import load_dotenv, find_dotenv
6
+
7
+ ### API Token Management
8
+ # API Tokens are used to authenticate clients to the device
9
+ # API Tokens are stored locally on the device in its .env file
10
+
11
+ def generate_token(length=8) -> tuple[str, str, str]:
12
+ random_bytes = secrets.token_bytes(length) # Generate a random byte string
13
+ token = base64.urlsafe_b64encode(random_bytes).decode('utf-8').rstrip('=') # Encode the byte string in a URL-safe base64 format
14
+ salt = os.urandom(16).hex() # 16 bytes of random salt
15
+ hashed = hashlib.sha256(bytes.fromhex(salt) + token.encode()).hexdigest() # Hash to sha256 standard
16
+ return salt, hashed, token
17
+
18
+ def validate_token(salt, hash, token) -> bool:
19
+ new_hashed = hashlib.sha256(bytes.fromhex(salt) + token.encode()).hexdigest()
20
+ return new_hashed == hash
21
+
22
+ def hash_token(token: str) -> tuple[str, str]:
23
+ salt = os.urandom(16).hex()
24
+ hashed = hashlib.sha256(bytes.fromhex(salt) + token.encode()).hexdigest()
25
+ return salt, hashed
26
+
27
+ # Example Usage:
28
+ # if __name__ == '__main__':
29
+ # okay = generate_token()
30
+ # assert validate_token(okay[0], okay[1], okay[2] + "s"), "Token validation failed!"
31
+ # print("Token validation succeeded!")
@@ -0,0 +1,5 @@
1
+ def list_to_str(list:list) -> str:
2
+ return ','.join(str(x) for x in list)
3
+
4
+ def str_to_list(s:str) -> list[int]:
5
+ return [int(x) for x in s.split(',')]