Python Django Interaction with Third Party Backend via Client Library - django

I am programming a web frontend and backend with Python Django for a FinTS client (https://python-fints.readthedocs.io/en/latest/).
The FinTS client library provides an API to communicate with a third party backend.
The communication with the FinTS client has to be done in multiple steps:
first connect
then the backend asks for a TAN number
the TAN number has to be provided
then transactions can be fetched
Basically the sequence looks like this:
Sequence
I am struggling with the question how I could realize this in detail with Django.
I did some experiences with Django, Django Channels and Websockets, but without real success.
I tried so far:
A Django view provides a Django form
The web client creates a websocket connection to a WebSocketConsumer
The WebSocketConsumer provides its Django channel name to the web client
The web client posts the form with credentials including the channel name
When the form is posted, the view sends a message via a Django Channel to a BackgroundWorker inlcluding the web socket channel name
The BackgroundWorker instantiates the FinTS client object and initiates the connection.
The BackgroundWorker sends a message to the WebSocketConsumer asking for the TAN
The WebSocketConsumer sends a web socket message to the web client to ask for the TAN
The web client sends the TAN via web socket message
Here I have the following problems:
Sending the message from the Django View to the BackgroundWorker in step 5 results in a weired type error (https://github.com/redis/redis-py/issues/2593)
ile "/mnt/d/Documents/python/myapp/myapp/.venv/lib/python3.8/site-packages/redis/asyncio/client.py", line 547, in parse_response
retval = self.response_callbacks[command_name](response, **options)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
2.
Even if this worked, the BackgroundWorker needs to instantiate the FinTS client object
class BackgroundWorker (AsyncConsumer):
async def start(self, event):
f = FinTS3PinTanClient(*client_args)
But where to store the reference f to the object for a specific client ? When the function terminates, the object is lost, but I still need later for sending the TAN number and requesting the transactions.
It seems that the FinTS library supports to serialize the current state, destruct the object and later reconstruct it with the serialized data.
But where to store the serialized data? In the database?
Alternatively the BackgroundWorker would somehow need to block and wait for another message from the WebSocket client. But this does not seem to be a good idea.
Is the approach with the BackgroundWorker the right idea?
Is a pure Websocket approach better? But I would like to use Django forms for the credentials form.
Maybe I am totally on the wrong track.
I am not so familiar with web frontends and backends - can somebody give me a hint how you would design the architecture could in a real production system?

Related

Create a persistent node-soap client

I have a cpp based soap application which supports multiple sessions. It follows this sequence
Create a new session. This returns a new session ID.
Make further requests on this same client to do some work which uses same process but unique thread assigned to this client will intercept these calls.
Close Session by providing the session ID. This will clean up the thread.
Now this is working fine when I'm using a cpp based client which creates a soap client like this
soap_init2(&soap, SOAP_IO_KEEPALIVE | SOAP_C_UTFSTRING, SOAP_IO_KEEPALIVE | SOAP_C_UTFSTRING);
Creats a session does some work on it and ends the session and finally calls
soap_destroy(&soap); soap_end (&soap); soap_done (&soap); // Cleanup soap context
to perform the cleanup of the client. But I want to achieve same thing using a node-js server/application for that I used node's soap module. Basic things seems to be working as well. For example I was able to make soap requests to the server for create session and some other tasks. But when I try to use the same session again my cpp application's worker thread is not intercepting these calls but every-time these calls to go my root session(the thread that initiated the soap server/or which initiates new sessions). Hence I'm not able to use the session management provided by the soap server.
Here is how I creates soap client.
const wsdlOptions = {
"envelopeKey": 'soapenv',
"disableCache": true,
connection: 'keep-alive'
};
soap.createClient(url, wsdlOptions, function (err, client) {
if (err) {
// Return job failure. As this is due to an SOAP client error, let us restart.
logUtils.log('SOAP Client creation failed.')
messenger.jobError(sessionID, jobID, true, Errors.CLIENT_CREATE_ERROR)
return
}
Basic communication is fine. My main problem is that post create all the function calls I make on this client should be treated like they are coming from same soap client so that cpp server can serve them on right session. Any suggestion how to mimic the client support provided by cpp-soap api's

Choosing the scenario of using Web Sockets in standard HTTP REST API

I will be happy to get advice from more experienced developers about adding Web Sockets into my HTTP-based project.
That’s the thing. I have developed the REST API based service. Everything works well enough, but… In some special cases my server needs a long time to serve client requests. It may be from 1 minute to several hours (and even days)! I implement some not-so-good algorithm to address this issue:
Client sends HTTP request
Server replies about registering request
Client starts sending HTTP requests to get necessary data (if response does not have needed information the client sends another request and so on)
That is all in a nutshell.
And it seems to be a bad scenario and I am trying to integrate web sockets for adding duplex-channels in this architecture. I hope that my API will be able to send info about updated data as soon as possible without the necessity of many requests from the client.
But I am a bit confused in choosing one of two ways to use web socket (WS).
Variant A.
The server only tells the client via WS that data is ready. And the client gets data by standard request-response HTTP method from REST API.
Variant B.
The server sends all data to the client via WS without HTTP at all.
What variant is more suitable? Or maybe some other variants?
I do not want to remove HTTP at all. I just try to implement WS for a particular kind of end-points.
Variant A would be more suitable and easy to implement. You can send message to the client after the data is ready, and he can then send request for the data. It will be like a simple chat websocket, and will serve your purpose.

Flask - websocket doesn't work correctly in a real server

I've developed a WebApp with Flask, where different threads check a status and, if something changes they send a new json to the client. Then the client, with the javascript, can update the html page.
Running the app in my LAN, different clients connect and everything work correctly.
If I run the app on a real server (such as AWS, by using "flask run --host=0.0.0.0" ), the clients can connect and show the web page, but they don't receive the json sent by the socket of the webapp.
In the WebApp, a thread sends the new json by calling a function that uses:
socketio.emit('update', {'number': new_json_FE}, namespace='/test')
While the javascript receives this message (and does something) in this way:
socket.on('update', function(msg) { ....}
It is very strange that the clients connected in the LAN receive correctly all the json sent by the socket, while in the web not: they only receive the json when they connect to, and I have to upload the page (they don't receive the socket messages).
Can you help me?
Thank you very much!
I would advise against the use of threads like you have described for this situation.
Instead I would probably create a new program, StatusUpdater, that is always running and which is connected via socket to your Flask-SocketIO backend. When it finds a change in status it sends w/e signal or payload it needs to, through a socket, to the Flask-Socketio server. The SocketIO server upon receipt of this StatusUpdater payload can then send a broadcast to all connected clients notifying the client of the update.

What is this distributed communication model called (client-server-engine)?

I'm looking for a communication model that is constructed the following way:
One or more clients can connect to a server
One (chess-)engine connects to the server
The information flow is only one way, e.g if any client sends a message to the server, the server will forward the message to the engine. But if the engine responds, it should first send the respond to the server which forwards the response to the specific client.
Additionally, do you have any ideas or code examples on how to program that using c++ with boost/beast?

Asynchronous Web Service & Web Service without response?

The concept of Asynchronous Web Service is a web service where the client does not have to wait to receive a response from the server. in AJAX this is implemented by having a callback function to process the response. So the server indeed still sends the response to the client.
Is it possible to have an Asynchronous Web Service without response? Is there any platform that provide this?
Thank you.
I have done asynch web services in the past. They are very useful. YOu do not need a detailed response but you at least need an HTTP response, like 200 OK. If the client that makes the request provides some sort of ID or key for that request, then the client can use the same ID/key to later on query for the result/response of the request.
As far as frameworks that provide this, I do not know of any. In the past I would just have a shared memory store, like Memcache, to store the state and result of the request. As long as the state is shared across all nodes, any node can then process the call back request.
EDIT: Providing a key in the request can be done in either REST or SOAP environment. HTTP provides multiple places where a key can be communicated.
GET query param (REST)
HTTP header (SOAP/REST)
Added to the message body of a POST request. This can be done through two ways.
param in the message body (REST)
variable or attribute in serialized object (SOAP/REST))