How to send local file from Flask to Reactjs - javascript

I have React JS as frontend and Flask as backend for my application. The idea is that the user upload image to react, then transfer to process in Flask and then Flask return the processed image back to React for display.
To send file from Flask to React, I saved the image in a local folder. So the order looks like this:
--node_modules,public,src // React files
--api //Flask files
-upload_image
-app.py
-...
So in Flask, I will send the url of the image from my local server to React like this:
#app.route('/get-cut-image',methods=["GET"])
def get_cut_img():
if path_is_valid:
return "http://127.0.0.1:5000/api/upload_image/img.png"
else:
return "No valid path"
and in React, I use axios to call the server:
export default class Body extends Component {
constructor(props) {
super(props);
this.state = {
images: "",
result: false,
upload: true,
};
this.getDatas = this.getDatas.bind(this);
}
getDatas() {
try {
const dataImage = axios.get(
"http://127.0.0.1:5000/get-cut-image"
);
this.setState({
images: dataImage.data,
});
} catch (error) {
console.log(error);
}
this.setState({result: true, upload: false});
}
render() {
return (
<img src={this.state.images}></img>
);
}
However, the server send the right url to image folder, however, I cannot get the url in client. Any help?
EDIT:
So I figure out that localhost:3000/ is the public folder of react. So my directories looks like this:
--node_modules,public,src // React files
--api //Flask files
-app.py
I have another function that process the image, and save the image to the public folder
#app.route('/upload', methods=['GET', 'POST'])
def upload_file():
img_BGRA = <some_processing> #return PIL image
img_BGRA.save(<home/user/.../public/filename.png>)
When I try to do so, in my react page crashes and restart again.

Related

Having trouble writing form input to a separate file

Currently I have a Next.js app with a form that looks like this:
import React from 'react'
function Form() {
return (
<div>
<form action="/api/newfile" method="post">
<label htmlFor="project">project Name</label>
<textarea width={100} height={100} type="text" name="project" required />
<button type="submit">Submit</button>
</form>
</div>
)
}
export default Form
With help from How to create file from /api in NextJS? I was able to get an API function set up that my form can interact with:
import fs from 'fs';
export default async function handler(req, res) {
const {
method,
body,
} = req
try {
switch (method) {
case 'POST':
fs.writeFileSync('./pages/api/newfilewithoutanextension', JSON.stringify(body))
break
default:
res.setHeader('Allow', ['GET', 'POST'])
res.status(405).end(`Method ${method} Not Allowed`)
}
return res.status(200).json({ message: 'Success' })
} catch (error) {
return res.status(500).json(error)
}
}
I fire up the app and at the /form page my input looks like this:
function() {
echo my form input
}
I am able to write my new file to disk without the file extension (this was correct by design), however the response is written in JSON. It looks like this:
{"project":"function() {\r\n echo \"my form input\"\r\n}"}
I need the newly generated file contents to look like that of my form input.
I have tried replacing the JSON.stringify(body) but seem to get everything but the response I need.

Can't get Plaid Link to Open using Javascript and python

When the plaid link handler is called it spins and then goes away. I can't get the link dialog box to show completely to get access token. Setup using flask for the python server on port 5000 and using the plaid api for calls in python. Using javascript on the client side.
I can see the requests going through but nothing happens or seems to post to the client:
127.0.0.1 - - [05/Apr/2022 21:53:31] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [05/Apr/2022 21:54:10] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [05/Apr/2022 21:54:10] "POST /create_link_token HTTP/1.1" 200 -
Javascript:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button id="link-button">Link Account</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<script type="text/javascript">
(async function($) {
var handler = Plaid.create({
// Create a new link_token to initialize Link
token: (await $.post('/create_link_token')).link_token,
receivedRedirectUri: window.location.href,
onLoad: function() {
// Optional, called when Link loads
},
onSuccess: function(public_token, metadata) {
// Send the public_token to your app server.
// The metadata object contains info about the institution the
// user selected and the account ID or IDs, if the
// Account Select view is enabled.
$.post('/exchange_public_token', {
public_token: public_token,
});
},
onExit: function(err, metadata) {
// The user exited the Link flow.
if (err != null) {
// The user encountered a Plaid API error prior to exiting.
}
// metadata contains information about the institution
// that the user selected and the most recent API request IDs.
// Storing this information can be helpful for support.
},
onEvent: function(eventName, metadata) {
// Optionally capture Link flow events, streamed through
// this callback as your users connect an Item to Plaid.
// For example:
// eventName = "TRANSITION_VIEW"
// metadata = {
// link_session_id: "123-abc",
// mfa_type: "questions",
// timestamp: "2017-09-14T14:42:19.350Z",
// view_name: "MFA",
// }
}
});
$('#link-button').on('click', function(e) {
handler.open();
});
})(jQuery);
</script>
</body>
</html>
Python server.py:
# source /Users/tnappy/node_projects/quickstart/python/bin/activate
# Read env vars from .env file
from plaid.exceptions import ApiException
from plaid.model.payment_amount import PaymentAmount
from plaid.model.payment_amount_currency import PaymentAmountCurrency
from plaid.model.products import Products
from plaid.model.country_code import CountryCode
from plaid.model.recipient_bacs_nullable import RecipientBACSNullable
from plaid.model.payment_initiation_address import PaymentInitiationAddress
from plaid.model.payment_initiation_recipient_create_request import PaymentInitiationRecipientCreateRequest
from plaid.model.payment_initiation_payment_create_request import PaymentInitiationPaymentCreateRequest
from plaid.model.payment_initiation_payment_get_request import PaymentInitiationPaymentGetRequest
from plaid.model.link_token_create_request_payment_initiation import LinkTokenCreateRequestPaymentInitiation
from plaid.model.item_public_token_exchange_request import ItemPublicTokenExchangeRequest
from plaid.model.link_token_create_request import LinkTokenCreateRequest
from plaid.model.link_token_create_request_user import LinkTokenCreateRequestUser
from plaid.model.asset_report_create_request import AssetReportCreateRequest
from plaid.model.asset_report_create_request_options import AssetReportCreateRequestOptions
from plaid.model.asset_report_user import AssetReportUser
from plaid.model.asset_report_get_request import AssetReportGetRequest
from plaid.model.asset_report_pdf_get_request import AssetReportPDFGetRequest
from plaid.model.auth_get_request import AuthGetRequest
from plaid.model.transactions_get_request import TransactionsGetRequest
from plaid.model.transactions_get_request_options import TransactionsGetRequestOptions
from plaid.model.identity_get_request import IdentityGetRequest
from plaid.model.investments_transactions_get_request_options import InvestmentsTransactionsGetRequestOptions
from plaid.model.investments_transactions_get_request import InvestmentsTransactionsGetRequest
from plaid.model.accounts_balance_get_request import AccountsBalanceGetRequest
from plaid.model.accounts_get_request import AccountsGetRequest
from plaid.model.investments_holdings_get_request import InvestmentsHoldingsGetRequest
from plaid.model.item_get_request import ItemGetRequest
from plaid.model.institutions_get_by_id_request import InstitutionsGetByIdRequest
from plaid.model.transfer_authorization_create_request import TransferAuthorizationCreateRequest
from plaid.model.transfer_create_request import TransferCreateRequest
from plaid.model.transfer_get_request import TransferGetRequest
from plaid.model.transfer_network import TransferNetwork
from plaid.model.transfer_type import TransferType
from plaid.model.transfer_user_in_request import TransferUserInRequest
from plaid.model.ach_class import ACHClass
from plaid.model.transfer_create_idempotency_key import TransferCreateIdempotencyKey
from plaid.model.transfer_user_address_in_request import TransferUserAddressInRequest
from plaid.api import plaid_api
from flask import Flask
from flask import render_template
from flask import request
from flask import jsonify
from datetime import datetime
from datetime import timedelta
import plaid
import base64
import os
import datetime
import json
import time
from dotenv import load_dotenv
from werkzeug.wrappers import response
import pyodbc
load_dotenv()
app = Flask(__name__)
cnxn = pyodbc.connect("Driver={SQL Server Native Client 11.0};"
"Server=DESKTOP-DJCMSVC\MJBOURQUIN_SQL;"
"Database=MyBudget;"
"Trusted_Connection=yes;")
cursor = cnxn.cursor()
cursor.execute('SELECT * FROM Accounts')
for row in cursor:
print('row = %r' % (row,))
vals = ("SOMETHING")
data = "UPDATE Accounts Set API_ID = 'SOMETHING' WHERE Id = 1"
cursor.execute(data)
cursor.commit();
access = "THAT THING"
cursor = cnxn.execute('UPDATE Accounts Set API_ID = ? WHERE Id = ?', [access,1])
cursor.commit();
# Fill in your Plaid API keys - https://dashboard.plaid.com/account/keys
PLAID_CLIENT_ID = os.getenv('PLAID_CLIENT_ID')
PLAID_SECRET = os.getenv('PLAID_SECRET')
# Use 'sandbox' to test with Plaid's Sandbox environment (username: user_good,
# password: pass_good)
# Use `development` to test with live users and credentials and `production`
# to go live
PLAID_ENV = os.getenv('PLAID_ENV', 'sandbox')
# PLAID_PRODUCTS is a comma-separated list of products to use when initializing
# Link. Note that this list must contain 'assets' in order for the app to be
# able to create and retrieve asset reports.
PLAID_PRODUCTS = os.getenv('PLAID_PRODUCTS', 'transactions').split(',')
# PLAID_COUNTRY_CODES is a comma-separated list of countries for which users
# will be able to select institutions from.
PLAID_COUNTRY_CODES = os.getenv('PLAID_COUNTRY_CODES', 'US').split(',')
products = []
for product in PLAID_PRODUCTS:
products.append(Products(product))
def empty_to_none(field):
value = os.getenv(field)
if value is None or len(value) == 0:
return None
return value
host = plaid.Environment.Sandbox
if PLAID_ENV == 'sandbox':
host = plaid.Environment.Sandbox
if PLAID_ENV == 'development':
host = plaid.Environment.Development
if PLAID_ENV == 'production':
host = plaid.Environment.Production
# Parameters used for the OAuth redirect Link flow.
#
# Set PLAID_REDIRECT_URI to 'http://localhost:3000/'
# The OAuth redirect flow requires an endpoint on the developer's website
# that the bank website should redirect to. You will need to configure
# this redirect URI for your client ID through the Plaid developer dashboard
# at https://dashboard.plaid.com/team/api.
PLAID_REDIRECT_URI = empty_to_none('PLAID_REDIRECT_URI')
configuration = plaid.Configuration(
host=host,
api_key={
'clientId': PLAID_CLIENT_ID,
'secret': PLAID_SECRET,
'plaidVersion': '2020-09-14'
}
)
api_client = plaid.ApiClient(configuration)
client = plaid_api.PlaidApi(api_client)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/my-link/')
def my_link():
print ('I got clicked!')
return 'Click.'
#app.route("/create_link_token", methods=['POST'])
def create_link_token():
# Get the client_user_id by searching for the current user
request = LinkTokenCreateRequest(
products=products,
client_name="Budgetary",
country_codes=list(map(lambda x: CountryCode(x), PLAID_COUNTRY_CODES)),
language='en',
user=LinkTokenCreateRequestUser(
client_user_id=str(time.time())
)
)
if PLAID_REDIRECT_URI!=None:
request['redirect_uri']=PLAID_REDIRECT_URI
# create link token
response = client.link_token_create(request)
return jsonify(response.to_dict())
#app.route('/exchange_public_token', methods=['POST'])
def exchange_public_token():
global access_token
public_token = request.form['public_token']
request = ItemPublicTokenExchangeRequest(
public_token=public_token
)
response = client.item_public_token_exchange(request)
access_token = response['access_token']
item_id = response['item_id']
cursor = cnxn.execute('UPDATE Accounts Set API_ID = ? WHERE Id = ?', [access_token,1])
cursor.commit();
return jsonify(response.to_dict())
if __name__ == '__main__':
app.run(debug=True)
Solved by breaking the code out into pieces. Clicking the button, then requesting and printing value in python. Then sending and making sure it's parsed correctly. Then with the parsed token value opening up link successfully.

How can I use main.dart variable in my JS file?

I'm trying to create a calling app using flutter and I've created the backend using a node.js. This is how my main.dart file in flutter looks like:
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:flutter_dialpad/flutter_dialpad.dart';
import 'dart:js';
import 'package:js/js.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child:
DialPad(
enableDtmf: true,
outputMask: "(000) 000-0000",
backspaceButtonIconColor: Colors.red,
makeCall: (number){
print(number);
}
)
),
),
);
}
}
I want to use this "number" variable in my app.js file which looks like this:
const accountSid = '***';
const authToken = '***';
const client = require('twilio')(accountSid, authToken);
client.calls.create({
url: 'http://demo.twilio.com/docs/voice.xml',
to: '+10000000',
from: '+1000000',
}, function(err, call){
if (err) {
console.log(err);
} else {
console.log(call.sid);
}
})
I want to be able to use the "number" variable from my main.dart file in the "to" field in my app.js file. Please help me out...
What you need is a way to pass data between applications, and the easiest way for that would be through a REST API
You can use the HTTP module in NodeJS or a third-party package like Express and set up a POST Route to your NodeJS Server, where the number is sent as data.
Once the data is received on your server, you can call your Twilio function, and send a response back.
On Flutter, you can use the http package to make the API call.

How to read from a csv file in a React app?

I built a super basic react app using the typescript version of create-react-app.
In my react app I want to display data from csv files I have added my project. Imagine a data.csv file under src.
On a button click I want to trigger a function that reads this file, uses some of the data for calculations etc and then prints the result. What's the best way to make this happen? I know how to trigger a function on button click in React but don't know what to do within that function to read the file and console log the data to start.
Important - I already have the file path and file in my project and do not need user input to find the file
I tried using things like fs within the function but those throw errors and I learnt its because they are native modules and cant be used on browser. So what can be used for browser?
fs only works on the server, not on the client. The browser doesn't have (general) access to the file system.
There are several options:
1. public folder
Put the .csv file into the public folder, then you can load it like:
function App() {
const [ text, setText ] = useState();
const load = function(){
fetch( './csvInPublicFolder.csv' )
.then( response => response.text() )
.then( responseText => {
setText( responseText );
})
};
return (
<div>
<button onClick={ load }>load</button>
<h2>text:</h2>
<pre>{ text }</pre>
</div>
);
}
2. webpack file-loader
Or, if the file has to be inside the src folder,
install: yarn add file-loader --dev
add a webpack.config.js:
module.exports = {
module: {
rules: [
{
test: /\.csv$/,
use: [
{
loader: 'file-loader',
},
],
},
],
},
};
And import the csv file like:
import csvFilePath from './csvInSrcFolder.csv';
import { useState } from 'react';
function App() {
const [ text, setText ] = useState();
const load = function(){
fetch( csvFilePath )
.then( response => response.text() )
.then( responseText => {
setText( responseText );
});
};
return (
<div>
<button onClick={ load }>load</button>
<h2>text:</h2>
<pre>{ text }</pre>
</div>
);
}
3. server
Or you can create a custom server.js and send a request to the server. On the server you have access to the file system (fs).
4. parse csv
if you don't want to parse the file content yourself, you can use an existing csv parser. Some people recommend papaparse (I don't have own experience about which ones are good)
import * as Papa from 'papaparse';
// ...
fetch( csvFilePath )
.then( response => response.text() )
.then( responseText => {
// -- parse csv
var data = Papa.parse(responseText);
console.log('data:', data);
});

Upload and read a file in react

Im trying to upload a file with React and see its contents, but what it gives me is C:\fakepath\. I know why it gives fakepath, but what is the correct way to upload and read the contents of a file in react?
<input type="file"
name="myFile"
onChange={this.handleChange} />
handleChange: function(e) {
switch (e.target.name) {
case 'myFile':
const data = new FormData();
data.append('file', e.target.value);
console.log(data);
default:
console.error('Error in handleChange()'); break;
}
},
To get the file info you want to use event.target.files which is an array of selected files. Each one of these can be easily uploaded via a FormData object. See below snippet for example:
class FileInput extends React.Component {
constructor(props) {
super(props)
this.uploadFile = this.uploadFile.bind(this);
}
uploadFile(event) {
let file = event.target.files[0];
console.log(file);
if (file) {
let data = new FormData();
data.append('file', file);
// axios.post('/files', data)...
}
}
render() {
return <span>
<input type="file"
name="myFile"
onChange={this.uploadFile} />
</span>
}
}
ReactDOM.render(<FileInput />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>
<div id="root"></div>
You may want to look into FileReader which can help if you want to handle the file on the client side, for example to display an image.
https://developer.mozilla.org/en-US/docs/Web/API/FileReader
You can use React Dropzone Uploader, which gives you file previews (including image thumbnails) out of the box, and also handles uploads for you.
In your onChangeStatus prop you can react to the file's meta data and the file itself, which means you can do any kind of client-side processing you want before or after uploading the file.
import 'react-dropzone-uploader/dist/styles.css'
import Dropzone from 'react-dropzone-uploader'
const Uploader = () => {
return (
<Dropzone
getUploadParams={() => ({ url: 'https://httpbin.org/post' })} // specify upload params and url for your files
onChangeStatus={({ meta, file }, status) => { console.log(status, meta, file) }}
onSubmit={(files) => { console.log(files.map(f => f.meta)) }}
accept="image/*,audio/*,video/*"
/>
)
}
Uploads have progress indicators, and they can be cancelled or restarted. The UI is fully customizable.
Full disclosure: I wrote this library.
Try to use Multer and gridfs-storage on the back end and store the fileID along with your mongoose schema.
// Create a storage object with a given configuration
const storage = require('multer-gridfs-storage')({
url: 'MONGOP DB ATLAS URL'
});
// Set multer storage engine to the newly created object
const upload = multer({ storage }).single('file');
router.post('/', upload, (req, res) => {
const newreminder = new Reminders({
category: req.body.category,
name:req.body.name,
type: req.body.type,
exdate: req.body.exdate,
location:req.body.location,
notes:req.body.notes,
fileID: req.file.id
});
newreminder.save(function(err){
if(err){
console.log(err);
return;
}
res.json({ "success": "true"});
});
});
Then on the front end treat it normally (with Axios) and upload the entire file and grab a hold of all the info in the normal react way:
onSubmit = (e) => {
e.preventDefault;
const formData = new FormData();
formData.append({ [e.target.name]: e.target.value })
formData.append('file', e.target.files[0]);
axios.post({
method:'POST',
url:'EXPRESS JS POST REQUEST PATH',
data: formData,
config:{ headers: {'Content-Type':'multipart/form-data, boundary=${form._boundary}'}}
})
.then(res => console.log(res))
.catch(err => console.log('Error', err))
}
Have you use dropzone ?
see this react-dropzone
easy implement, upload and return url if this important.
onDrop: acceptedFiles => {
const req = request.post('/upload');
acceptedFiles.forEach(file => {
req.attach(file.name, file);
});
req.end(callback);
}
You can use FileReader onload methods to read the file data and then can send it to the server.
You can find this useful to handle files using File Reader in React ReactJS File Reader
To add to the other answers here, especially for anyone new to React, it is useful to understand that react handles forms a little differently than people may be used to.
At a high level, react recommends using 'Controlled components" :
In most cases, we recommend using controlled components to implement forms. In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself.
This essentially means that the user input, e.g. a text field, is also a state of the component and as the user updates it the state is updated and the value of the state if displayed in the form. This means the state and the form data are always in synch.
For an input type of file this will not work because the file input value is read-only. Therefore, a controlled component cannot be used and an 'uncontrolled component' is used instead.
In React, an is always an uncontrolled component because its value can only be set by a user, and not programmatically.
The recommended way to input a file type (at the time of writing) is below, from the react documentation here https://reactjs.org/docs/uncontrolled-components.html#the-file-input-tag:
class FileInput extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.fileInput = React.createRef();
}
handleSubmit(event) {
event.preventDefault();
alert(
`Selected file - ${this.fileInput.current.files[0].name}`
);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Upload file:
<input type="file" ref={this.fileInput} />
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
}
ReactDOM.render(
<FileInput />,
document.getElementById('root')
);
The documentation includes a codepen example which can be built on.

Categories

Resources