For context, I have an enterprise level subscription to an API provider which includes real-time financial data via a WebSocket protocol. However, the documentation only gives guidance on how to use the WebSocket with Python and NodeJS. I want to establish a connection to the WebSocket via R so I can stream real-time financial data, specifically using the 'websocket' library. Here is the code the API documentation provides for python users.
import websocket
import simplejson as json
import time
import ssl
ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
ws.connect("wss://websockets.financialmodelingprep.com")
login = {
'event':'login',
'data': {
'apiKey': "<key>",
}
}
subscribe = {
'event':'subscribe',
'data': {
'ticker': "aapl",
}
}
unsubscribe = {
'event':'unsubscribe',
'data': {
'ticker': "aapl",
}
}
ws.send(json.dumps(login))
time.sleep(1)
ws.send(json.dumps(subscribe))
time.sleep(1)
ws.send(json.dumps(unsubscribe))
while True:
print(ws.recv())
I tried to use the WebSocket$new() function in R but I keep getting errors, and I'm assuming this is because I'm not adding my credentials properly. Here is the code I'm trying to use:
WebSocket$new(
url = 'wss://crypto.financialmodelingprep.com/',
headers = list(
login = "{
'event' = 'login',
'data' = {'apiKey' : <key>}
}"
)
)
And here is the error I am getting:
<WebSocket>
Public:
clearAccessLogChannels: function (channels = c("all"))
clearErrorLogChannels: function (channels = c("all"))
clone: function (deep = FALSE)
close: function (code = 1000L, reason = "")
connect: function ()
initialize: function (url, protocols = character(0), headers = NULL, autoConnect = TRUE,
onClose: function (callback)
onError: function (callback)
onMessage: function (callback)
onOpen: function (callback)
protocol: function ()
readyState: function ()
send: function (msg)
setAccessLogChannels: function (channels = c("all"))
setErrorLogChannels: function (channels = c("all"))
Private:
accessLogChannels: function (channels, stompValue)
accessLogChannelValues: none connect disconnect control frame_header frame_paylo ...
callbacks: environment
errorLogChannels: function (channels, stompValue)
errorLogChannelValues: none devel library info warn rerror fatal all
getInvoker: function (eventName)
pendingConnect: FALSE
wsObj: externalptr
I've also tried following this tutorial but again, it doesn't help me figure out my problem.
Would anyone know how I can successfully establish this connection in R? Thanks in advance.
Related
I am new to angular and i want to display JSON data from python to angular with the help of node.js and I used child process to connect python and node.js but I dont know how to pass it to angular service
node.js file
const express = require('express')
const { spawn } = require('child_process')
const app = express()
const port = 8000
app.get('/', (req, res) => {
let dataToSend
let largeDataSet = []
// spawn new child process to call the python script
const python = spawn('python', ['test.py'])
// collect data from script
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...')
//dataToSend = data;
largeDataSet.push(data)
})
// in close event we are sure that stream is from child process is closed
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`)
// send data to browser
res.send(largeDataSet.join(''))
})
})
app.listen(port, () => {
console.log(`App listening on port ${port}!`)
})
Technically you just have to send a Http GET request from your service.
I suggest that you should read and follow this offical http client guide to set it up correctly.
Here is a simple service snippet. This should be enough.
#Injectable({
providedIn: 'root',
})
export class MyService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
const url = '';
return this.http.get(url);
}
}
So I have some Swift code that send a request to my local host
//
// ContentView.swift
// Shared
//
// Created by Ulto4 on 10/23/21.
//
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
Text("Hello, world!")
.padding()
Button(action : {
self.fu()
}, label: {
Image(systemName: "pencil").resizable().aspectRatio(contentMode:.fit)
})
}
}
func fu(){
let url = URL(string: "http://127.0.0.1:5000/232")
guard let requestUrl = url else { fatalError() }
var request = URLRequest(url: requestUrl)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Error took place \(error)")
return
}
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
However, on my Flask app there are no get requests coming in and the function isn't running. There also isn't anything printing to the console.
I am fairly new to swift so I don't really know how to fix this.
Is there any other way to send requests in swift, if not, How would I fix this?
You are creating the URLSessionDataTask, but you never start it. Call task.resume(), e.g.
func performRequest() {
guard let url = URL(string: "http://127.0.0.1:5000/232") else {
fatalError()
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error took place \(error)")
return
}
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
}
task.resume() // you must call this to start the task
}
That having been said, a few caveats:
You are doing http rather than https. Make sure to temporarily enable insecure network requests with app transport settings, e.g.
You didn’t say if this was for macOS or iOS.
If running on physical iOS device, it will not find your macOS web server at 127.0.0.1 (i.e., it will not find a web server running on your iPhone). You will want to specify the IP number for your web server on your LAN.
If macOS, make sure to enable outbound network requests in the target’s “capabilities”:
You asked:
Is there any other way to send requests in swift?
It is probably beyond the scope of your question, but longer term, when using SwiftUI, you might consider using Combine, e.g., dataTaskPublisher. When running a simple “what was the status code” routine, the difference is immaterial, but when you get into more complicated scenarios where you have to parse and process the responses, Combine is more consistent with SwiftUI’s declarative patterns.
Let us consider a more complicated example where you need to parse JSON responses. For illustrative purposes, below I am testing with httpbin.org, which echos whatever parameters you send. And I illustrate the use of dataTaskPublisher and how it can be used with functional chaining patterns to get out of the mess of hairy imperative code:
struct SampleObject: Decodable {
let value: String
}
struct HttpBinResponse<T: Decodable>: Decodable {
let args: T
}
class RequestService: ObservableObject {
var request: AnyCancellable?
let decoder = JSONDecoder()
#Published var status: String = "Not started yet"
func startRequest() {
request = createRequest().sink { completion in
print("completed")
} receiveValue: { [weak self] object in
self?.status = "Received " + object.value
}
}
func createRequest() -> AnyPublisher<SampleObject, Error>{
var components = URLComponents(string: "https://httpbin.org/get")
components?.queryItems = [URLQueryItem(name: "value", value: "foo")]
guard let url = components?.url else {
fatalError("Unable to build URL")
}
return URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: HttpBinResponse<SampleObject>.self, decoder: decoder)
.map(\.args)
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
struct ContentView: View {
#ObservedObject var requestService = RequestService()
var body: some View {
VStack{
Text("Hello, world!")
.padding()
Button {
requestService.startRequest()
} label: {
Image(systemName: "pencil").resizable().aspectRatio(contentMode:.fit)
}
Text(requestService.status)
}
}
}
But, like I said, it is beyond the scope of this question. You might want to make sure you get comfortable with SwiftUI and basic URLSession programming patterns (e.g., making sure you resume any tasks you create). Once you have that mastered, you can come back to Combine to write elegant networking code.
FWIW, like workingdog said, you could also use the new async-await rendition of data(for:delegate:). But when in the declarative world of SwiftUI, I would suggest Combine.
Writing my first Lambda funcation to put item with Python
The problem im having - not getting the input from the registration form ( front end hosted on S3 bucket with static webhost enabled ) to the DynamoDB table
the Data will be sent with this funcation to the API hosted on AWS
const BASE_URL = `API-URL`;
function handleForm() {
const name = document.querySelector('#name').value;
const email = document.querySelector('#email').value;
const phone = document.querySelector('#phone').value;
const data = {
name,
email,
phone
}
console.log(data);
saveDataToAWS(data);
}
async function saveDataToAWS(data) {
const result = await axios.post(BASE_URL, data);
return result.data;
}
Im not sure im using AXIOS the right way but lets continue
The Lambda funcation im using now is pretty much this :
import json
import boto3
dynamodb=boto3.resource('dynamodb')
table=dynamodb.Table('register')
def lambda_handler(event, context):
table.put_item(
Item={
'name'=event['name'],
'email'=event['email'],
'phone'=event['phone']
}
)
respone={
'mes':'Good input !'
}
return {
'statusCode': 200,
'body': respone
}
Im pretty much 99% new to writting code in AWS so im sure im doing most of it wrong
Really looking for you help !
The 'event' attribute has a 'body' parameter that will contain the data in your example:
data = json.loads(event["body"])
table.put_item(
Item={
'name':data['name'],
'email':data['email'],
'phone':data['phone']
}
)
Remember to check CloudWatch Logs as well, as it will tell you whether the Lambda was invoked in the first place, and if it failed.
More information on the structure of the event-attribute can be found here:
https://aws-lambda-for-python-developers.readthedocs.io/en/latest/02_event_and_context/
I have a server written in python and an Android client written in Kotlin (in Android Studio IDE). I use sockets for maintaining this connection. After the client sends a message to the server, the server will need to send an answer to the client. I didn't find a way to receive data at the client by using sockets. I tried to do that:
var server = Socket(serverIP, serverPort)
server.outputStream.write(message.toByteArray())
var answer = server.inputStream.bufferedReader().use(BufferedReader::readText)
server.close()
but it seems not to work. If it matters, the sending at server side looks like that:
client.send(message.encode())
I suppose, you are using OkHttp for this. In my app I have the following code
private fun getClient(): OkHttpClient {
return try {
val builder = OkHttpClient.Builder()
builder.pingInterval(30, TimeUnit.SECONDS)
builder.build()
} catch (e: Exception) {
throw RuntimeException(e)
}
}
class WebSocketController(
val callback: SomeCallback
) {
private val url = "wss://your.url.com/"
private val socketClient = getClient()
private var serverSocket: WebSocket? = null
private val listener = object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
super.onOpen(webSocket, response)
val json = "" // your payload to send on connect
serverSocket = webSocket
serverSocket!!.send(json)
}
override fun onMessage(webSocket: WebSocket, text: String) {
super.onMessage(webSocket, text)
val data = Json.decodeFromString<YourModel>(text)
// here you can use your data from server
callback.makeSomething(data)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
super.onFailure(webSocket, t, response)
callback.onFailure(t)
}
}
fun establishConnection() {
socketClient.newWebSocket(requestBuilder().build(), listener)
}
fun disconnect() {
val json = "" // your payload on disconnect
serverSocket?.send(json)
}
private fun requestBuilder(): Request.Builder = Request.Builder().url(url)
}
I have a Node.js application which is currently a web-based API. For one of my API functions, I make a call to a short Python script that I've written to achieve some extra functionality.
After reading up on communicating between Node and Python using the child_process module, I gave it a try and achieved my desired results. I call my Node function that takes in an email address, sends it to Python through std.in, my Python script performs the necessary external API call using the provided e-mail, and writes the output of the external API call to std.out and sends it back to my Node function.
Everything works properly until I fire off several requests consecutively. Despite Python correctly logging the changed e-mail address and also making the request to the external API with the updated e-mail address, after the first request I make to my API (returning the correct data), I keep receiving the same old data again and again.
My initial guess was that Python's input stream wasn't being flushed, but after testing the Python script I saw that I was correctly updating the e-mail address being received from Node and receiving the proper query results.
I think there's some underlying workings of the child_process module that I may not be understanding... since I'm fairly certain that the corresponding data is being correctly passed back and forth.
Below is the Node function:
exports.callPythonScript = (email)=>
{
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
return getPythonData;
}
And here is the Python script:
import sys
from emailage.client import EmailageClient
def read_in():
lines = sys.stdin.readlines()
return lines[0]
def main():
client = EmailageClient('key','auth')
email = read_in()
json_response = client.query(email,user_email='authemail#mail.com')
print(json_response)
sys.stdout.flush()
if __name__ == '__main__':
main()
Again, upon making a single call to callPythonScript everything is returned perfectly. It is only upon making multiple calls that I'm stuck returning the same output over and over.
I'm hitting a wall here and any and all help would be appreciated. Thanks all!
I've used a Mutex lock for this kind of example. I can't seem to find the question the code comes from though, as I found it on SO when I had the same kind of issue:
class Lock {
constructor() {
this._locked = false;
this._waiting = [];
}
lock() {
const unlock = () => {
let nextResolve;
if (this._waiting.length > 0) {
nextResolve = this._waiting.pop(0);
nextResolve(unlock);
} else {
this._locked = false;
}
};
if (this._locked) {
return new Promise((resolve) => {
this._waiting.push(resolve);
});
} else {
this._locked = true;
return new Promise((resolve) => {
resolve(unlock);
});
}
}
}
module.exports = Lock;
Where I then call would implement it like this, with your code:
class Email {
constructor(Lock) {
this._lock = new Lock();
}
async callPythonScript(email) {
const unlock = await this._lock.lock();
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
await unlock();
return getPythonData;
}
}
I haven't tested this code, and i've implemented where i'm dealing with arrays and each array value calling python... but this should at least give you a good start.