Skip to content

Commit

Permalink
Merge pull request #42 from lexara-prime-ai/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
lexara-prime-ai authored Jun 6, 2024
2 parents 6fa74ba + a643f2b commit 84b048c
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 61 deletions.
6 changes: 3 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "wspr_cdk",
"image": "mcr.microsoft.com/devcontainers/rust:bullseye",
"postCreateCommand": "bash .devcontainer/post_create.sh",
"name": "wspr_cdk_development_container",
"dockerFile": "Dockerfile",
"postCreateCommand": "bash ./scripts/bash/entrypoint.sh",
"customizations": {
"vscode": {
"extensions": [
Expand Down
13 changes: 0 additions & 13 deletions .devcontainer/post_create.sh

This file was deleted.

3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/**/target
/**/target
service_account.json
10 changes: 6 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,18 @@ ENV ROCKET_PORT=8000
# Build the project
RUN cargo build --workspace --release

COPY /scripts/bash/entrypoint.sh /scripts/bash/entrypoint.sh
RUN chmod +x /scripts/bash/entrypoint.sh

#------------------------------------

# [CURRENT] entry point.
# Run maturin develop during container initialization
ENTRYPOINT ["/bin/bash", "-c", ". /opt/venv/bin/activate && maturin develop -m python_wrapper/Cargo.toml && ./target/release/wspr_cdk_server"]
# Run maturin develop on container initialization.
ENTRYPOINT ["/scripts/bash/entrypoint.sh"]

#------------------------------------

EXPOSE 8000

# NOTES #
# End users need to provide/generate their own <service_account.json> credentials.
# pip install patchelf
# End users need to provide/generate their own <service_account.json> credentials.
111 changes: 77 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,59 @@

`wspr_cdk` provides an abstraction for accessing and analyzing **WSPR** (_Weak Signal Propagation Reporter_) real-time spot data. This crate allows you to perform queries and fetch data from the WSPR database with ease.

## Prerequisites

When running the application, ensure that the `service_account.json` file has been set up correctly. This file contains the authentication _credentials_ needed to access the **Google Drive API**.

- If this file is _missing_ or _incorrectly configured_, you will encounter an authentication error when attempting to upload files to Google Drive.

Here's a step-by-step guide to ensure proper setup:

1. **Create a Service Account**:
- Go to the Google Cloud Console.
- Navigate to the IAM & Admin > Service Accounts page.
- Click "Create Service Account".
- Fill out the necessary details and click "Create".
2. **Generate a JSON Key**:

- After creating the service account, click on the service account you created.
- Go to the "Keys" tab.
- Click "Add Key", then select "Create new key".
- Choose **JSON** as the key type and click "Create". This will download a JSON file containing your credentials.

3. **Provide Necessary Permissions**:
- Ensure that the service account has the required permissions to access Google Drive. You can grant the necessary permissions by assigning the appropriate roles to the service account.
4. **Configure Environment**:
- Place the downloaded `service_account.json` file in the appropriate location accessible to your application. Ensure that the file is named exactly `service_account.json`.
- If running the application in a Docker container, make sure the `service_account.json` file is _mounted_ into the container at runtime.

These steps should ensure that the `service_account.json` file is correctly set up, thus allowing the `server` module to **authenticate** with Google Cloud successfully and avoid encountering the authentication _error mentioned_.

### Usage

- To run the **Python** server, use:

```sh
docker run -it wspr_cdk python ./hyper/hyper/server.py --interval 5
```

- To run the **Rust** server, use:

```sh
docker run -e ROCKET_ADDRESS=0.0.0.0 -e ROCKET_PORT=8000 -it wspr_cdk rust
```

## Features

- Fetch **WSPR** spot data in various formats (**JSON**, **JSONCompact**, **JSONEachRow**)
- Easy integration with **Tokio** for asynchronous operations
- Abstractions to manage session state and dispatch actions to the **ClickHouse** client
- **Server component** for accessing and sharing real-time data via HTTP
- Fetch **WSPR** spot data in various formats (**JSON**, **JSONCompact**, **JSONEachRow**)
- Easy integration with **Tokio** for asynchronous operations
- Abstractions to manage session state and dispatch actions to the **ClickHouse** client
- **Server component** for accessing and sharing real-time data via HTTP

### Upcoming Features

- **Mutual TLS** for secure client-server communications
- **SSL (OpenSSL)** support for encrypted data transfer
- **Mutual TLS** for secure client-server communications
- **SSL (OpenSSL)** support for encrypted data transfer

## Installation

Expand All @@ -21,15 +63,15 @@ To use this crate, add `wspr_cdk` to your `Cargo.toml`:
```toml
[dependencies]
wspr_cdk = "0.0.8"
```
```

## Environment Variable

Before using the crate, ensure you set the following environment variable:

```sh
export BASE_URL=http://db1.wspr.live/
```
```

## Usage

Expand Down Expand Up @@ -61,13 +103,13 @@ async fn main() {
let json_response = serde_json::to_string_pretty(&response).unwrap();
println!("{}", json_response);
}
```
```

### Example Query

```sh
wget -q -O - "http://db1.wspr.live/?query=SELECT * FROM wspr.rx LIMIT 5 FORMAT JSON;"`
```
```

### Sample Output

Expand Down Expand Up @@ -101,7 +143,7 @@ ClickHouseState {
],
STATUS: "Fetching all records.",
}
```
```

## Server Component

Expand Down Expand Up @@ -142,48 +184,49 @@ async fn get_wspr_spots() -> Result<Json<Vec<WsprSpot>>, status::Custom<String>>
async fn rocket() -> _ {
rocket::build().mount("/", routes![get_wspr_spots])
}
```
```

### Sample cURL Request

To fetch WSPR spots using the server component, you can use the following cURL command:

```sh
curl -X GET http://localhost:8000/api/spots
```
```

## Client-Side Usage Example

You can also fetch WSPR data using client-side JavaScript. Here is a sample implementation:

```html
<!DOCTYPE html>
<!doctype html>
<html>
<head>
<head>
<title>WSPR Spots</title>
</head>
<body>
</head>
<body>
<div id="demo"></div>
<script> const content = document.getElementById("demo");
async function getData() {
let response = await fetch("http://localhost:8000/api/spots");
let raw = await response.json();
for (let i of raw) {
console.log(i);
content.innerHTML += `
<script>
const content = document.getElementById("demo");
async function getData() {
let response = await fetch("http://localhost:8000/api/spots");
let raw = await response.json();
for (let i of raw) {
console.log(i);
content.innerHTML += `
<h2>Spot id: ${i.id}</h2>
<p>Time: ${i.time}</p>
<p>Band: ${i.band}</p>
`;
}
}
getData();
</script>
</body>
}
getData();
</script>
</body>
</html>
```
```

## WSPR Guidelines

Expand All @@ -207,10 +250,10 @@ The `wspr_cdk` is also available as a Docker image:

```sh
docker pull lexaraprime/wspr_cdk:master
```
```

You can find it on Docker Hub: [lexaraprime/wspr_cdk](https://hub.docker.com/layers/lexaraprime/wspr_cdk/master/images/sha256-c869961d9a8413bf8ee562c3507632aeaa4b6e720a97792e7eef5ad984437872?context=repo)

---------------------------------
---

This documentation is also available as a crate on [crates.io](https://crates.io/)
This documentation is also available as a crate on [crates.io](https://crates.io/)
3 changes: 2 additions & 1 deletion hyper/hyper/drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ def upload_to_drive(file_path):
service = build("drive", "v3", credentials=credentials)

file_metadata = {
"name": "wspr_spot_data.csv",
"name": constants.FILE_NAME.strip(),
"parents": [constants.PARENT_FOLDER_ID],
}

print("[Uploading] file to Google Drive...\n")
print("\n[Waiting]\nPress CTRL + C to exit...\n")

service.files().create(body=file_metadata, media_body=file_path).execute()
except Exception as e:
Expand Down
22 changes: 17 additions & 5 deletions hyper/hyper/server.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import argparse
import asyncio
import csv
import os
Expand All @@ -9,8 +10,9 @@


class Server:
def __init__(self):
self.write_path = os.path.join(constants.FILE_PATH, "wspr_spot_data.csv")
def __init__(self, interval):
self.write_path = os.path.join(constants.FILE_PATH, constants.FILE_NAME)
self.interval = interval

async def write_to_csv(self):
"""
Expand All @@ -19,7 +21,7 @@ async def write_to_csv(self):
"""

try:
output = await python_wrapper.python_wrapper.get_wspr_spots("100000", "JSON")
output = await python_wrapper.python_wrapper.get_wspr_spots("10", "JSON")
data = output.get_data()

# Display data that's being fetched for [DEBUG] purposes.
Expand Down Expand Up @@ -143,10 +145,20 @@ async def display_data(self, data):
print("Code:", code_field)

async def __call__(self):
await self.write_to_csv()
while True:
await self.write_to_csv()
await asyncio.sleep(self.interval)


server = Server()
def parse_args():
parser = argparse.ArgumentParser(description="WSPR Spot Data Server")
parser.add_argument(
"--interval", type=int, default=900, help="Sleep interval in seconds"
)
return parser.parse_args()


if __name__ == "__main__":
args = parse_args()
server = Server(args.interval)
asyncio.run(server())
16 changes: 16 additions & 0 deletions scripts/bash/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

source /opt/venv/bin/activate

maturin develop -m python_wrapper/Cargo.toml

# Check for arguments to determine the mode of operation.
if [[ "$1" == "python" ]]; then
shift
exec python3 "$@"
elif [[ "$1" == "rust" ]]; then
exec ./target/release/wspr_cdk_server
else
echo "Invalid option. Use 'python' to run the Python server or 'rust' to run the Rust server."
exit 1
fi
7 changes: 7 additions & 0 deletions scripts/bash/inspect_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

printf "\n[Inspecting] <test> container...\n"
sudo docker run -it test python ./hyper/hyper/server.py --interval 5

# To do -> Add commands for inspecting resulting image
# docker image inspect [OPTIONS] IMAGE [IMAGE...]

0 comments on commit 84b048c

Please sign in to comment.