Hello if i have a flag in one script, is it possible to pass real time change on others? I mean that, for example i wrote this script. let's name it script1.py which reads data from a serial communication and saves it to a .txt file. When the data that i receive is '0' i would like to pass the flag sent_json to script2. So when script2 gets the trigger, POST the data. Any suggestions ?
while True:
try :
a = ser.readline()
timestamped = str(datetime.datetime.now())
suma = timestamped + "\t " + a.decode('utf-8')
f = open("current_data.txt", 'a')
f.write(suma)
if (a.decode().strip() == '0'):
sent_json = True
saveData()
print("New data is saved!")
sent_json = False
except :
print("Unexpected error: ")
break
and i have another script, lets name it script2.py, in which is the main Flask app :
import sqlite3, json
from flask import Flask, render_template, request
from serialNumber_id import serial_number
import sys
app = Flask(__name__)
#app.route("/")
def PostData():
''' Connect to DB, set the temperature to 2 decimal float, POST Data to DB'''
with open("data.json") as dataFile:
data = json.load(dataFile)
for key, value in data.items():
temperature = "{0:.2f}".format(float(value['data']))
date = value['date']
conn = sqlite3.connect('sensordata.db')
cur = conn.cursor()
cur.execute( """INSERT INTO Temperature_data(temperature, currentdat, currenttime, device) VALUES ((?) , (?), time("now"), (?))""", (temperature, date, serial_number))
conn.commit()
open('data.json', 'w').close()
#######
Code something like
while True:
if sent_json :
do something
else:
do something
# if __name__ == "__main__":
# app.run(host='0.0.0.0', port=8181, debug=True)
Note that i have tried in script2
from script1 import sent_json
Also the scripts are in the same folder.
So the absolute simplest thing to do, since you're polling anyway, is to write to some kind of shared resource like a file. So script1 writes something, maybe a timestamp, to a file, and script2 continually polls that file to check to see whether it's changed.
Let me warn you that this, like anything that relies on the filesystem, is a terrible solution if you want performance or efficiency.
Why not just POST the data to your flask app instead of trying to pass it from script to script?
#script1.py
import requests
my_data = {'name':'FooBar'}
requests.post('http://localhost:3000/', json=data)
#script2.py
from flask import request
...
#app.route("/", methods=["POST"])
def PostData():
data = request.get_json(force=True)
print(data)
# {'name':'FooBar'}
do_something(data)
Related
I have this following python code for a Flask server. I am trying to have this part of the code list all my vehicles that match the horsepower that I put in through my browser. I want it to return all the car names that match the horsepower, but what I have doesn't seem to be working? It returns nothing. I know the issue is somewhere in the "for" statement, but I don't know how to fix it.
This is my first time doing something like this and I've been trying multiple things for hours. I can't figure it out. Could you please help?
from flask import Flask
from flask import request
import os, json
app = Flask(__name__, static_folder='flask')
#app.route('/HORSEPOWER')
def horsepower():
horsepower = request.args.get('horsepower')
message = "<h3>HORSEPOWER "+str(horsepower)+"</h3>"
path = os.getcwd() + "/data/vehicles.json"
with open(path) as f:
data = json.load(f)
for record in data:
horsepower=int(record["Horsepower"])
if horsepower == record:
car=record["Car"]
return message
The following example should meet your expectations.
from flask import Flask
from flask import request
import os, json
app = Flask(__name__)
#app.route('/horsepower')
def horsepower():
# The type of the URL parameters are automatically converted to integer.
horsepower = request.args.get('horsepower', type=int)
# Read the file which is located in the data folder relative to the
# application root directory.
path = os.path.join(app.root_path, 'data', 'vehicles.json')
with open(path) as f:
data = json.load(f)
# A list of names of the data sets is created,
# the performance of which corresponds to the parameter passed.
cars = [record['Car'] for record in data if horsepower == int(record["Horsepower"])]
# The result is then output separated by commas.
return f'''
<h3>HORSEPOWER {horsepower}</h3>
<p>{','.join(cars)}<p>
'''
There are many different ways of writing the loop. I used a short variant in the example. In more detail, you can use these as well.
cars = []
for record in data:
if horsepower == int(record['Horsepower']):
cars.append(record['Car'])
As a tip:
Pay attention to when you overwrite the value of a variable by using the same name.
Am trying to add a new record into a python document and I think am stuck with an issue caused by the curl post function. I have attached the python file and the error received when posting to my url. Could anyone kindly point me towards the right direction.
I dont understand the error code to identify whether the problem comes from the python code bu I do suspect an issue with the curl url.
#!/usr/bin/python
import json
from bson import json_util
from bson.json_util import dumps
import bottle
from bottle import route, run, request, abort
#imports for database
from pymongo import MongoClient
connection = MongoClient('localhost', 27017)
db = connection['city']
collection = db['inspections']
# set up URI paths for REST service
#route('/hello', method='GET')
def get_hello():
word = '"'+request.GET.get('name', None)+'"'
string="{hello:"+word+"}"
return json.loads(json.dumps(string, indent=4, default=json_util.default))
#route('/strings', method='POST')
def run_post():
first = '"'+request.json.get('string1')+'"'
second = '"'+request.json.get('string2')+'"'
data="{first:"+first+",second:"+ second+"}"
return json.loads(json.dumps(data, indent=4, default=json_util.default))
#route('/create', method='POST')
def run_create():
myid = request.json.get('id')
print(myid)
cert_number = request.json.get('certificate_number')
bus_name = request.json.get('business_name')
date = request.json.get('date')
result = request.json.get('result')
sector = request.json.get('sector')
added_id = collection.insert({"id":myid,"certificate_number":cert_number,"business_name":bus_name,"date":date,"result":result,"sector":sector})
added_doc = collection.find_one({"_id":added_id})
return json.loads(json.dumps(added_doc, indent=4, default=json_util.default))
#url does not allow spacing when passing an argument,
#therefore i use underscores when passing the business_name and the remove them
#when creating the query
#route('/read', method='GET')
def get_read():
word = request.params.get('business_name')
word = word.replace("_"," ")
found_doc = collection.find({"business_name":{'$regex':word}}) #will still get results when user pass parameter with white space
return dumps(found_doc)
#route('/update', method='GET')
def get_update(rslt = "Violation Issued"):
myid = request.query.id
query = { "id" :myid}
new_update = { "$set":{"result":rslt}}
collection.update_one(query,new_update)
updated_doc = collection.find_one({"id":myid})
return json.loads(json.dumps(updated_doc, indent=4, default=json_util.default))
#route('/delete', method='GET')
def get_update():
myid = request.query.id
query = {"id" :myid};
print(query)
result = collection.delete_one(query)
return "document with id "+myid+" Has beed deleted from the City Collection"
if __name__ == '__main__':
run(debug=True,reloader = True)
#run(host='localhost', port=8080)
Error:
Returned HTML:
python error:
The Problem is that at one point in the json in your curl request you used “ instead of ". Therefore the json parser throws an error.
So instead of
"business_name" : “ACME Test INC."
write:
"business_name" : "ACME Test INC."
Not sure if you solved this but here we go. Jakob was correct that you used “ instead of "
Next, get the values from the document you are inserting
data = request.json (Contains parsed content)
Assign a value to the variables you need such as id
id = data['id']
Store all the values in a dictionary variable (I think it is much cleaner this way)
document = {"id":myid,"certificate_number":cert_number,"business_name":bus_name,"date":date,"result":result,"sector":sector}
Lastly, use insert_one and catch errors
try:
collection.insert_one(document)
print("CREATED NEW DOCUMENT")
except Exception as e:
print("ERROR: ", e)
Also, there are several ways to fix the "space" problem you mention for cURL requests.
One way is to simply add a %20 between spaces like so:
ACME%20TEST%20INC.
I hope that helps.
I am trying to run a python3 program file and am getting some unexpected behaviors.
I'll start off first with my PATH and env setup configuration. When I run:
which Python
I get:
/c/Program Files/Python36/python
From there, I cd into the directory where my python program is located to prepare to run the program.
Roughly speaking this is how my python program is set up:
import modulesNeeded
print('1st debug statement to show program execution')
# variables declared as needed
def aFunctionNeeded():
print('2nd debug statement to show fxn exe, never prints')
... function logic...
if __name__ == '__main__':
aFunctionNeeded() # Never gets called
Here is a link to the repository with the code I am working with in case you would like more details as to the implementation. Keep in mind that API keys are not published, but API keys are in local file correctly:
https://github.com/lopezdp/API.Mashups
My question revolves around why my 1st debug statements inside the files are printing to the terminal, but not the 2nd debug statements inside the functions?
This is happening in both of the findRestaurant.py file and the geocode.py file.
I know I have written my if __name__ == '__main__': program entry point correctly as this is the same exact way I have done it for other programs, but in this case I may be missing something that I am not noticing.
If this is my output when I run my program in my bash terminal:
$ python findRestaurant.py
inside geo
inside find
then, why does it appear that my aFunctionNeeded() method shown in my pseudo code is not being called from the main?
Why do both programs seem to fail immediately after the first debug statements are printed to the terminal?
findRestaurant.py File that can also be found in link above
from geocode import getGeocodeLocation
import json
import httplib2
import sys
import codecs
print('inside find')
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)
foursquare_client_id = "..."
foursquare_client_secret = "..."
def findARestaurant(mealType,location):
print('inside findFxn')
#1. Use getGeocodeLocation to get the latitude and longitude coordinates of the location string.
latitude, longitude = getGeocodeLocation(location)
#2. Use foursquare API to find a nearby restaurant with the latitude, longitude, and mealType strings.
#HINT: format for url will be something like https://api.foursquare.com/v2/venues/search?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&v=20130815&ll=40.7,-74&query=sushi
url = ('https://api.foursquare.com/v2/venues/search?client_id=%s&client_secret=%s&v=20130815&ll=%s,%s&query=%s' % (foursquare_client_id, foursquare_client_secret,latitude,longitude,mealType))
h = httplib2.Http()
result = json.loads(h.request(url,'GET')[1])
if result['response']['venues']:
#3. Grab the first restaurant
restaurant = result['response']['venues'][0]
venue_id = restaurant['id']
restaurant_name = restaurant['name']
restaurant_address = restaurant['location']['formattedAddress']
address = ""
for i in restaurant_address:
address += i + " "
restaurant_address = address
#4. Get a 300x300 picture of the restaurant using the venue_id (you can change this by altering the 300x300 value in the URL or replacing it with 'orginal' to get the original picture
url = ('https://api.foursquare.com/v2/venues/%s/photos?client_id=%s&v=20150603&client_secret=%s' % ((venue_id,foursquare_client_id,foursquare_client_secret)))
result = json.loads(h.request(url, 'GET')[1])
#5. Grab the first image
if result['response']['photos']['items']:
firstpic = result['response']['photos']['items'][0]
prefix = firstpic['prefix']
suffix = firstpic['suffix']
imageURL = prefix + "300x300" + suffix
else:
#6. if no image available, insert default image url
imageURL = "http://pixabay.com/get/8926af5eb597ca51ca4c/1433440765/cheeseburger-34314_1280.png?direct"
#7. return a dictionary containing the restaurant name, address, and image url
restaurantInfo = {'name':restaurant_name, 'address':restaurant_address, 'image':imageURL}
print ("Restaurant Name: %s" % restaurantInfo['name'])
print ("Restaurant Address: %s" % restaurantInfo['address'])
print ("Image: %s \n" % restaurantInfo['image'])
return restaurantInfo
else:
print ("No Restaurants Found for %s" % location)
return "No Restaurants Found"
if __name__ == '__main__':
findARestaurant("Pizza", "Tokyo, Japan")
geocode.py File that can also be found in link above
import httplib2
import json
print('inside geo')
def getGeocodeLocation(inputString):
print('inside of geoFxn')
# Use Google Maps to convert a location into Latitute/Longitute coordinates
# FORMAT: https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=API_KEY
google_api_key = "..."
locationString = inputString.replace(" ", "+")
url = ('https://maps.googleapis.com/maps/api/geocode/json?address=%s&key=%s' % (locationString, google_api_key))
h = httplib2.Http()
result = json.loads(h.request(url,'GET')[1])
latitude = result['results'][0]['geometry']['location']['lat']
longitude = result['results'][0]['geometry']['location']['lng']
return (latitude,longitude)
The reason you're not seeing the output of the later parts of your code is that you've rebound the standard output and error streams with these lines:
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
sys.stderr = codecs.getwriter('utf8')(sys.stderr)
I'm not exactly sure why those lines are breaking things for you, perhaps your console does not expect utf8 encoded output... But because they don't work as intended, you're not seeing anything from the rest of your code, including error messages, since you rebound the stderr stream along with the stdout stream.
This question already has answers here:
How to download a file over HTTP?
(30 answers)
Closed 7 years ago.
While building a flask website, I'm using an external JSON feed to feed the local mongoDB with content. This feed is parsed and fed while repurposing keys from the JSON to keys in Mongo.
One of the available keys from the feed is called "img_url" and contains, guess what, an url to an image.
Is there a way, in Python, to mimic a php style cURL? I'd like to grab that key, download the image, and store it somewhere locally while keeping other associated keys, and have that as an entry to my db.
Here is my script up to now:
import json
import sys
import urllib2
from datetime import datetime
import pymongo
import pytz
from utils import slugify
# from utils import logger
client = pymongo.MongoClient()
db = client.artlogic
def fetch_artworks():
# logger.debug("downloading artwork data from Artlogic")
AL_artworks = []
AL_artists = []
url = "http://feeds.artlogic.net/artworks/artlogiconline/json/"
while True:
f = urllib2.urlopen(url)
data = json.load(f)
AL_artworks += data['rows']
# logger.debug("retrieved page %s of %s of artwork data" % (data['feed_data']['page'], data['feed_data']['no_of_pages']))
# Stop we are at the last page
if data['feed_data']['page'] == data['feed_data']['no_of_pages']:
break
url = data['feed_data']['next_page_link']
# Now we have a list called ‘artworks’ in which all the descriptions are stored
# We are going to put them into the mongoDB database,
# Making sure that if the artwork is already encoded (an object with the same id
# already is in the database) we update the existing description instead of
# inserting a new one (‘upsert’).
# logger.debug("updating local mongodb database with %s entries" % len(artworks))
for artwork in AL_artworks:
# Mongo does not like keys that have a dot in their name,
# this property does not seem to be used anyway so let us
# delete it:
if 'artworks.description2' in artwork:
del artwork['artworks.description2']
# upsert int the database:
db.AL_artworks.update({"id": artwork['id']}, artwork, upsert=True)
# artwork['artist_id'] is not functioning properly
db.AL_artists.update({"artist": artwork['artist']},
{"artist_sort": artwork['artist_sort'],
"artist": artwork['artist'],
"slug": slugify(artwork['artist'])},
upsert=True)
# db.meta.update({"subject": "artworks"}, {"updated": datetime.now(pytz.utc), "subject": "artworks"}, upsert=True)
return AL_artworks
if __name__ == "__main__":
fetch_artworks()
First, you might like the requests library.
Otherwise, if you want to stick to the stdlib, it will be something in the lines of:
def fetchfile(url, dst):
fi = urllib2.urlopen(url)
fo = open(dst, 'wb')
while True:
chunk = fi.read(4096)
if not chunk: break
fo.write(chunk)
fetchfile(
data['feed_data']['next_page_link'],
os.path.join('/var/www/static', uuid.uuid1().get_hex()
)
With the correct exceptions catching (i can develop if you want, but i'm sure the documentation will be clear enough).
You could put the fetchfile() into a pool of async jobs to fetch many files at once.
https://docs.python.org/2/library/json.html
https://docs.python.org/2/library/urllib2.html
https://docs.python.org/2/library/tempfile.html
https://docs.python.org/2/library/multiprocessing.html
I want to retrieve some values I put in the data store with a model class name "Ani" and I have tried using the script below to do that but I am having problem with. Can someone please, help me with it
import random
import getpass
import sys
# Add the Python SDK to the package path.
# Adjust these paths accordingly.
sys.path.append('/root/google_appengine')
sys.path.append('/root/google_appengine/lib/yaml/lib')
from google.appengine.ext.remote_api import remote_api_stub
from google.appengine.ext import db
import models
# Your app ID and remote API URL path go here.
APP_ID = 'silasanio'
REMOTE_API_PATH = '/remote_api'
def auth_func():
email_address = raw_input('Email address: ')
password = getpass.getpass('Password: ')
return email_address, password
def initialize_remote_api(app_id=APP_ID,
path=REMOTE_API_PATH):
remote_api_stub.ConfigureRemoteApi(
app_id,
path,
auth_func)
remote_api_stub.MaybeInvokeAuthentication()
def main():
initialize_remote_api()
Meanvalue = []
result = db. ("SELECT * FROM Ani ORDER BY date DESC LIMIT 1")
for res in result:
Meanvalue = res.mean
std_dev = res.stdev
print(mean)
if __name__ == '__main__':
main()
I am getting the error below:
raise KindError('No implementation for kind \'%s\'' % kind)
google.appengine.ext.db.KindError: No implementation for kind 'Ani'
Please, I need some help with it.
Thanks
You need to import the file where you define the class Ani before you can run queries on the data.