Render React components based on data from Python/Flask - python

I'm trying my hand at building a simple CMS with React, Flask, and MongoDB. I am trying to find a way to get data from MongoDB through Flask to render the correct React components.
The data is stored in MongoDB as:
{
title: "home",
modules: {
headerBlock: {
title: "My Website"
byline: "Some other text here"
}
}
}
I can get that data into Python fairly easily, but then I need to get Flask to render the React components. It would translate to:
<Header title="My Website" byline="Some other text here" />
So there needs to be some way for Flask to provide a container and information about which components to render. (There will be more than one component).
Any help or tips or pushes in the right direction would be appreciated!

It depends, if you are trying to build a single page application SPA , with react in front end, you would need to pass data from your back-end (flask) to react as json data.
Flask has a function called jsonify that reponse to json.

Related

Python to post and format API response data into Slack channel

Working on a script to present data in Slack channel.. I have a script I'm working on to request and return data that I need to post in the channel that gets invoked with a Slash command, but having an issue with presenting the data in the slack channel from where I've executed the Slash command. I've been attempting to work with the Block Kit Builder, but I see no way of presenting that data coming back from my script using the template I created.
Then in the Block kit builder, I can kind of see the format I want and send it to Slack from the Block kit builder, but if I wanted my return response from my Python script to be formatted by the template and respond in the channel, it doesn't seem to work.. I'm thinking I'm definitely doing something wrong, but was looking for suggestions..
I've been searching on possibly how to do it in Flask, which is what I'm using to execute a Slash command in Slack to invoke my Python script to query the API, get the response and send it to Slack..
Thanx.
P.S. Stackflow won't allow me to post a snippet of the json and/or images.. yet... something about a '10 reputation'...
I was able to figure this out. In my code, I reflected this:
for i in pdjson:
t = {}
try:
t["text"] = {
"type": "plain_text",
"text": f'{i["escalation_policy"]["summary"]} - Layer: {i["escalation_level"]}'
}
except (KeyError):
t["text"] = {
"type": "plain_text",
"text": f'{i["escalation_policy"]["summary"]} - Layer: {i["escalation_level"]}'
}
t["value"] = i["user"]["summary"]
Now I can present in the slack workspace with the block kit template. Now I just have to figure out how make the 'value' show up once I select an item in the list.

Fetch Flask Data from python

I have some code from python that displays a table using Flask and render template. I'd like to place this into my React App.js file how can I do this?
My CRUD from python
I'd like to place that into App.js.
Thanks in Advance.
You can create API in flask and call from react js with axios package.
Install axios with
npm install axios
Simple Example:
Suppose you API is localhost:8080/hello
and it returns "Hello world"
In app.js imports,
import axios from "axios";
and in return
return (
<div>
axios.get("localhost:8080/hello")
</div>
)
References:
https://www.npmjs.com/package/axios

Can I generate a REST service from a GraphQL schema?

I'd like to build a Django app with both a GraphQL endpoint and a REST API. Maintaining both separately would be too much of a pain; I'm looking for a good way to only maintain the GraphQL service and have the REST endpoints generated automagically.
Does anyone know about a good way to do this?
I know there are ways to build a GraphQL server on top of REST endpoints, but I'd rather have it the other way around, as the REST API requirement might go away in the future.
If you don't mind using Node.js, there is a library that does that (graphql2rest): https://github.com/sisense/graphql2rest
You can use it to automatically generate a REST API from your existing GraphQL schema.
"GraphQL2REST is a Node.js library that reads your GraphQL schema and a user-provided manifest file and automatically generates an Express router with fully RESTful HTTP routes — a full-fledged REST API."
If your only problem is not having a dedicated client on the client side and you can live with long urls your graphql endpoint is your RESTlike API. Disclaimer: Untested code for educational purposes only ;)
Read all posts:
GET /api/posts
=>
GET /graphql?query={posts{id title body}}
Create a post
POST /api/posts
{ "title": "Hello", "body": "world" }
=>
POST /graphql?query=mutation m($title:String!,$body:String!){createPost(title:$title,body:$body){id title body}
{ "variables": { "title": "Hello", "body": "world" } }
Your code can then work in a REST like manner (imagine redux actions calling REST APIs).
If you want something more in terms of a server, you can easily reverse what you discribed here:
I know there are ways to build a GraphQL server on top of REST endpoints,
You can build a proxy that rewrites your REST queries to GraphQL queries. This might be much easier than mapping a REST endpoint to GraphQL since your GraphQL API is much more powerful.
Some node.js express code since I don't know any python :(
const Lokka = require('lokka').Lokka;
const Transport = require('lokka-transport-http').Transport;
const express = require('express');
const client = new Lokka({
transport: new Transport('...')
});
const app = express();
app.get('/api/posts', (req, res) => {
client.query('{posts{id title body}}').then(result => {
res.status(200).send(result);
}).catch(error => {
res.status(500).end(); // Or other error handling
});
});

Using PhoneGap + Google App Engine to Upload and Save Images

Goal: Take/attach pictures in a PhoneGap application and send a public URL for each picture to a Google Cloud SQL database.
Question 1: Is there a way to create a Google Cloud Storage object from a base64 encoded image (in Python), then upload that object to a bucket and return a public link?
I'm looking to use PhoneGap to send images to a Python Google App Engine application, then have that application send the images to a Google Cloud Storage bucket I have set up, then return a public link back to the PhoneGap app. These images can either be taken directly from the app, or attached from existing photo's on the user's device.
I use PhoneGap's FileTransfer plugin to upload the images to GAE, which are sent as base64 encoded images (this isn't something I can control).
Based on what I've found in Google Docs, I can upload the images to Blobstore; however, it requires <input type='file'> elements in a form. I don't have 'file' input elements; I just take the image URI returned from PhoneGap's camera object and display a thumbnail of the picture that was taken (or attached).
Question 2: Is it possible to have an <input type='file'> element and control it's value? As in, is it possible to set it's value based on whether the user chooses a file, or takes a picture?
Thanks in advance!
Here's a solution for others who might face this problem. Turns out it's incredibly simple!
Once you have a bucket setup for your GAE project, you can use this Python code to send an image to the bucket:
import cloudstorage as gcs
import webapp2
import cgi
import MySQLdb
import os
import logging
import time
from google.appengine.api import mail
from google.appengine.api import images
from google.appengine.ext import blobstore
class UploadImageHandler(webapp2.RequestHandler):
def post(self):
self.response.headers.add_header(ACCESS_CONTROL, '*')
f = self.request.POST['image']
fname = '/your-bucket-name/%s' % f.filename;
gcs_file = gcs.open(fname, 'w', content_type="image/jpeg")
gcs_file.write(self.request.get('image'))
gcs_file.close()
And the code used to upload the file from a PhoneGap application:
// Uploads images in "imageURIs" to the web service specified in "server".
function uploadImages(imageURIs, server) {
var success = function(data) {
alert("Successfully uploaded image!");
};
var fail = function(error) {
alert("Failed to upload image: "+error);
};
var options = new FileUploadOptions();
options.fileKey = "image";
options.mimeType = "image/jpeg";
var ft = new FileTransfer();
for (var i = 0; i < imageURIs.length; i++) {
alert("Uploading"+i);
options.fileName = imageURIs[i].substr(imageURIs[i].lastIndexOf('/') + 1);
ft.upload(imageURIs[i], encodeURI(server), success, fail, options);
}
}
I hope it helps someone else. :)
Yes, that is a fine use for GAE and GCS. You do not need an <input type=file>, per se. You can just set up POST parameters in your call to your GAE url. Make sure you send a hidden key as well, and work from SSL-secured urls, to prevent spammers from posting to your app.

How do I handle an AJAX POST on Google App Engine Python 2.5 with webapp.RequestHandler?

Quick Summary: I'm creating a Chrome extension that talks to a Python 2.5 runtime application on App Engine that queries an SQL database in Google Cloud SQL. Tutorials for App Engine are largely of the getting started variety, and I can't find any tutorials on how to properly handle an AJAX post to the app.
Design: Chrome Extension input creates an AJAX Post > Python App > SQL DB.
Python runtime: 2.5
Host: App Engine hosts app, Cloud SQL hosts SQL database
The Chrome extension is making the AJAX call, but nothing is happening on App Engine.
When running the Python app directly from it's URL (I have test code that allows me to submit a variable to the search class directly) it's able to return the correct results, so the query and database connection work.
The issue I'm having is that I'm:
(a) Not sure if my AJAX request is even hitting the Python app
(b) Not sure if I'm handling the AJAX request correctly (i.e. reading in the data from it and responding with the output)
I've poured through the documentation and examples online but I can't find one that really outlines how to get an AJAX query to interact with a hosted Python app on AppEngine. If anyone sees any glaring errors or can point me towards relevant documentation I'd be very grateful!
Chrome Extension HTML
<head>
<script src='jquery-1.5.1.js'></script>
<script type="text/javascript">
function storeInput(value) {
$.ajax({
url: '<url>'
type: 'POST',
data: {'term': value},
dataType: 'text',
success: function (data) {
console.log('boom: ', data);
//var response = '<p class="desc_line"><span class="desc_title">Name: </span><span class="desc_text">' + eval(data) + '</p>';
},
error: function(data) {
console.log('no chance');
}
});
}
$(function() {
//when the page loads
$('.input-form').live('submit', function(e) {
e.preventDefault();
var formInput = $(this).find('.term-input').val();
storeInput(formInput);
});
});
</script>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
App Engine Python code
from __future__ import with_statement
import cgi
import urllib
from google.appengine.api import rdbms
from google.appengine.api import files
from google.appengine.ext import db
from google.appengine.ext import webapp
from django.utils import simplejson
from google.appengine.ext.webapp.util import run_wsgi_app
_INSTANCE_NAME = '<instance>'
def Parse
# redacted since this works fine to work through strings passed to it and turn them into proper SQL queries.
class Search(webapp.RequestHandler):
def post(self):
#Create connection to database
conn = rdbms.connect(instance=_INSTANCE_NAME, database='salesinfo')
cursor = conn.cursor()
# ideally set the body of the AJAX call to a variable but thats not working
user_input = self.request.body
# Parse input
sql_query = []
for value in Parse(user_input):
sql_query.append(value)
# Try first query
cursor.execute(sql_query[0])
# If first query yields no results, try the second query
if cursor.rowcount < 1:
cursor.execute(sql_query[1])
for row in cursor.fetchall():
output = row[0]
self.response.out.write(output) # ideally respond with the result
conn.close()
application = webapp.WSGIApplication(
[('/', Search)], #removed request
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
Too many possible problems here. I think you are trying to do too many things at once. Your code, at the first glance, makes sense.
I'd start by running the backend app locally and checking if the AJAX code is correct before bundling it inside a Chrome extension. I'm not sure if it's easy to debug in there (I'd suspect it is, but I never tried). In any case, by running the JavaScript code against your local dev server, you'll get a better idea if you are hitting the server. It will also be easier to see what's going on.
You can also try to do the AJAX call with a XmlHTTPRequest. This would remove jQuery from the equation.
Also, the logging module is your friend - you can - and should - log debugging events during debugging.

Categories

Resources