I have below query stored in a variable I got and I need to fetch value of 'resource_status'.
I need 'UPDATE_IN_PROGRESS'
As requested, putting the code here. The variable evntsdata is storing the events list.
try:
evntsdata = str(hc.events.list(stack_name)[0]).split(" ") # this is the variable that is getting the JSON response (or so)
#print(evntsdata[715:733])
#event_handle = evntsdata[715:733]
if event_handle == 'UPDATE_IN_PROGRESS':
loopcontinue = True
while loopcontinue:
evntsdata = str(hc.events.list(stack_name)[0]).split(" ")
#event_handle = evntsdata[715:733]
if (event_handle == 'UPDATE_COMPLETE'):
loopcontinue = False
print(str(timestamp()) + " " + "Stack Update is Completed!" + ' - ' + evntsdata[-3] + ' = ' + evntsdata[-1])
else:
print(str(timestamp()) + " " + "Stack Update in Progress!" + ' - ' + evntsdata[-3] + ' = ' + evntsdata[-1])
time.sleep(10)
else:
print("No updates to perform")
exit(0)
except AttributeError as e:
print(str(timestamp()) + " " + "ERROR: Stack Update Failure")
raise
print(evntsdata) has below result
['<Event', "{'resource_name':", "'Stackstack1',", "'event_time':", "'2017-05-26T12:10:43',", "'links':", "[{'href':", "'x',", "'rel':", "'self'},", "{'href':", "'x',", "'rel':", "'resource'},", "{'href':", "'x',", "'rel':", "'stack'}],", "'logical_resource_id':", "'Stackstack1',", "'resource_status':", "'UPDATE_IN_PROGRESS',", "'resource_status_reason':", "'Stack", 'UPDATE', "started',", "'physical_resource_id':", "'xxx',", "'id':", "'xxx'}>"]
Do not serialize and parse objects when the data is in front of you. This is inefficient and hard to understand and maintain. The solution is quite trivial:
data = hc.events.list(stack_name)[0].to_dict()
event_handle = data['resource_status']
It's not JSON, it's a class that you've printed
class Event(base.Resource):
def __repr__(self):
return "<Event %s>" % self._info
Try poking around the source code to get access to the dictionary self._info, then access your fields according
For example,
event_info = hc.events.list(stack_name)[0]._info
event_handle = event_info['resource_status']
Though, there may be another way like calling to_dict() instead, since the underscore indicates a private variable
Related
I've tried for hours to attempt to solve this myself so I can learn. I'm able to get the Family I want out of Revit (called familyToUpdate) and list the family (symbol) types, but I can't get the type name itself only their ID's. I want to compare the actual Type Name against a text parameter I called (typeToDelete) so that I can delete only the types I know are not being used. I've been through numerous examples but can never get them to work.
Here is my code to date:
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
app = doc.Application
familyToUpdate = "MyFamily"
typeToDelete = "MyFamilyType"
print "Family Name = " + familyToUpdate
print "Type To Delete = " + typeToDelete
#Delete Family Type
Elements = FilteredElementCollector(doc).OfClass(Family).ToElements()
for m in Elements:
try:
if m.Name.startswith((familyToUpdate)):
symbols = list(m.GetFamilySymbolIds())
for i in symbols:
print "Family Type Id = " + str(i)
famsymbol = doc.GetElement(i)
print "famsymbol = " + str(famsymbol)
#symbolName = famsymbol.Family.Name
#print symbolName
#if symbolName == typeToDelete:
# print "I found the type name"
except:
pass
Answered it myself. Work on it for hours, then FINALLY post a question. Take one more look at it, and there it is!!!
Here's the code for anyone else in the future fumbling through what I did:
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
app = doc.Application
familyToUpdate = "VA Titleblock Consultant Logo (PIN07)"
typeToDelete = "VA Titleblock Consultant Logo (PIN07) (Hagerman)"
print "Family Name = " + familyToUpdate
print "Type To Delete = " + typeToDelete + "\n\n"
#Delete Family Type
Elements = FilteredElementCollector(doc).OfClass(Family).ToElements()
for m in Elements:
try:
if m.Name.startswith((familyToUpdate)):
symbols = list(m.GetFamilySymbolIds())
for i in symbols:
#print "Family Type Id = " + str(i)
famsymbol = doc.GetElement(i)
#print "Symbol ID = " + str(famsymbol)
symbolName = famsymbol.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()
print "SymbolName = " + symbolName
except:
pass
Thank you for the solution. In it, you are retrieving the symbol name from the SYMBOL_NAME_PARAM built-in parameter. That is perfectly valid. An easier and more direct way to read the symbol name is to simply query the Element.Name property. Element is the parent class of all Revit database resident objects, including FamilySymbol.
Element.Name will not work because of multi-level inheritance. try the following instead:
name = Element.Name.GetValue(familysymbol)
Right now, I am using fine-uploader as my front-end and python-flask as my backend. What I need to do is that I need to send large files from the front end to my server. I can do this easily without concurrent chunking. But once I turn it on, the file gets corrupted. I think this is because when you concurrently chunk, I would guess part 7 could get added before part 5 gets added. Again, non-concurrent chunking is OK since it is sequential.
I need to know if there is some sort of temporary, global variable or way that I can store the chunk parts temporarily. I tried redis but unfortunately when I get the data from the redis, it shows a decoding error because probably redis tries to turn it into a string when I just need it to be bytes.
If all else fails, I'll just go to my last resort, which is to put the parts into their own little files then open them later on to combine them one by one.
Here is my code for your reference. It still has the redis methods on it.
def upload_temp_file_part(redis, request):
try:
# Remember the paramName was set to 'file', we can use that here to grab it
file = request.files['qqfile']
uuid = request.form['qquuid']
part = request.form['qqpartindex']
offset = request.form['qqpartbyteoffset']
key_content = 'file_content_' + uuid + part
key_offset = 'file_offset_' + uuid + part
value_content = file.stream.read()
value_offset = offset
logging.info("Setting part " + part + " of " + uuid)
redis.set(key_content, value_content)
redis.set(key_offset, value_offset)
except Exception as e:
logging.error(e)
def combine_temp_file_part(redis, request):
try:
uuid = request.form['qquuid']
total_parts = request.form['qqtotalparts']
save_path = os.path.join(os.getenv('UPLOAD_FOLDER_TEMP'), uuid)
with open(save_path, 'ab') as f:
for index in range(0, int(total_parts)):
key_content = 'file_content_' + uuid + str(index)
key_offset = 'file_offset_' + uuid + str(index)
logging.info("Get part " + str(index) + " of " + uuid)
value_content = redis.get(key_content)
value_offset = redis.get(key_offset)
if value_content is None or value_offset is None:
pass
# Throw Error
logging.info("Placing part " + str(index) + " of " + uuid)
f.seek(value_offset)
f.write(value_content)
redis.delete(value_offset)
redis.delete(value_content)
except Exception as e:
logging.error(e)
I've got a Python script that checks an API for train data using requests and prints out relevant information based on information stored in dictionaries. This works fine in the console, but I'd like for it to be accessible online, for this I've been recommend to use Flask.
However, I can't get around using the Flask's function/returns in the routes to get the same output as I get in the console. I've gotten as far as getting the the requests module imported, but this throws up a HTTPError 400 when I use my actual code.
How would I go about getting the console output printed out into a page? Here is my current code:
import requests
import re
from darwin_token import DARWIN_KEY
jsonToken = DARWIN_KEY
train_station = {'work_station': 'whs', 'home_station': 'tth', 'connect_station': 'ecr'}
user_time = {'morning_time': ['0821', '0853'], 'evening_time': ['1733'], 'connect_time': ['0834', '0843']}
def darwinChecker(departure_station, arrival_station, user_time):
response = requests.get("https://huxley.apphb.com/all/" + str(departure_station) + "/to/" + str(arrival_station) + "/" + str(user_time), params={"accessToken": jsonToken})
response.raise_for_status() # this makes an error if something failed
data1 = response.json()
train_service = data1["trainServices"]
print('Departure Station: ' + str(data1['crs']))
print('Arrival Station: ' + str(data1['filtercrs']))
print('-' * 40)
try:
found_service = 0 # keeps track of services so note is generated if service not in user_time
for index, service in enumerate(train_service): # enumerate adds index value to train_service list
if service['sta'].replace(':', '') in user_time: # replaces sta time with values in user_time
found_service += 1 # increments for each service in user_time
print('Service RSID: ' + str(train_service[index]['rsid']))
print('Scheduled arrival time: ' + str(train_service[index]['sta']))
print('Scheduled departure time: ' + str(train_service[index]['std']))
print('Status: ' + str(train_service[index]['eta']))
print('-' * 40)
if service['eta'] == 'Cancelled':
print('The ' + str(train_service[index]['sta']) + ' service is cancelled.')
print('Previous train departure time: ' + str(train_service[index - 1]['sta']))
print('Previous train status: ' + str(train_service[index - 1]['eta']))
if found_service == 0: # if no service is found
print('The services currently available are not specified in user_time.')
except TypeError:
print('There is no train service data')
try:
NRCCRegex = re.compile('^(.*?)[\.!\?](?:\s|$)') # regex pulls all characters until hitting a . or ! or ?
myline = NRCCRegex.search(data1['nrccMessages'][0]['value']) # regex searches through nrccMessages
print('\nNRCC Messages: ' + myline.group(1) + '\n') # prints parsed NRCC message
except (TypeError, AttributeError) as error: # tuple catches multiple errors, AttributeError for None value
print('\nThere is no NRCC data currently available\n')
print('Morning Journey'.center(50, '='))
darwinChecker(train_station['home_station'], train_station['connect_station'], user_time['morning_time'])
The only thing I can think of is that I'd have to split each print statement in a function and a corresponding return?
Any help/clarification would be much appreciated!
Is there a way to pass an HTTP verb (PATCH/POST) to a function and dynamically use that verb for Python requests?
For example, I want this function to take a 'verb' variable which is only called internally and will either = post/patch.
def dnsChange(self, zID, verb):
for record in config.NEW_DNS:
### LINE BELOW IS ALL THAT MATTERS TO THIS QUESTION
json = requests.verb(headers=self.auth, url=self.API + '/zones/' + str(zID) + '/dns_records', data={"type":record[0], "name":record[1], "content":record[2]})
key = record[0] + "record with host " + record[1]
result = json.loads(json.text)
self.apiSuccess(result,key,value)
I realize I cannot requests.'verb' as I have above, it's meant to illustrate the question. Is there a way to do this or something similar? I'd like to avoid an:
if verb == 'post':
json = requests.post(headers=self.auth, url=self.API + '/zones/' + str(zID) + '/dns_records', data={"type":record[0], "name":record[1], "content":record[2]}
else:
json = requests.patch(headers=self.auth, url=self.API + '/zones/' + str(zID) + '/dns_records', data={"type":record[0], "name":record[1], "content":record[2]}
Thanks guys!
Just use the requests.request() method. First argument is the HTTP verb that you want to use. requests.get(), requests.post(), etc. are just aliases to request('GET'), request('POST'): see the doc
Your code becomes:
verb = 'POST'
response = requests.request(
verb,
headers=self.auth,
url=self.API + '/zones/' + str(zID) + '/dns_records',
data={"type":record[0], "name":record[1], "content":record[2]}
)
With the request library, the requests.request method can be relied on directly (as Guillaume's answer suggested).
However, when encountering against libraries that don't have a generic method for methods that have similar calling signatures, getattr can be supplied with the name of the desired method as a string with a default value. Maybe like
action = getattr(requests, verb, None)
if action:
action(headers=self.auth, url=self.API + '/zones/' + str(zID) + '/dns_records', data={"type":record[0], "name":record[1], "content":record[2]})
else:
# handle invalid action as the default value was returned
For the default value it can be a proper action, or just leave it out and an exception will be raised; it's up to you how you want to handle it. I left it as None so you can deal with alternative case in the else section.
The purpose of the code is to use SOQL to query the SalesForce API, then to format the data and do some stuff before putting putting it into an oracle database. My code successfully handles the first and third part but the second part keeps breaking.
The code is using Python 2.7 with the standard C python compiler on Windows 7.
The SOQL is
SELECT ID, Name, Type, Description, StartDate, EndDate, Status
FROM CAMPAIGN
ORDER BY ID
This query pulls back a few hundred results in a JSON Dict.
I have to pull each record (Record contains ID, Name, Type, Description, StartDate, EndDate, and Status) one at a time and pass them to a function that generates the proper SQL to put the data in the proper Oracle Database. All of the results of the query come back as Unicode strings.
After I query the data and try to pass it to the function to generate the SQL to insert it into the Oracle database is where the trouble shows up.
Here is the section of code where the error occurs.
keys = ['attributes', 'Id', 'Name', 'Type', 'Description', 'StartDate', 'EndDate', 'Status']
for record in SrcData['records']: #Data cleaning in this loop.
processedRecs = []
if record['Description'] is not None:
record['Description'] = encodeStr(record['Description'])
record['Description'] = record['Description'][0:253]
for key in keys:
if key == 'attributes':
continue
elif key == 'StartDate' and record[key] is not None:
record[key] = datetime.datetime.strptime(record[key], "%Y-%m-%d")
elif key == 'EndDate' and record[key] is not None:
record[key] = datetime.datetime.strptime(record[key], "%Y-%m-%d")
else:
pass
processedRecs.append(record[key])
sqlFile.seek(0)
Query = RetrieveSQL(sqlFile, processedRecs)
The key list is because there was issues with looping on SrcData.keys().
the encodeStr function is:
def encodeStr(strToEncode):
if strToEncode == None:
return ""
else:
try:
tmpstr = strToEncode.encode('ascii', 'ignore')
tmpstr = ' '.join(tmpstr.split())
return tmpstr
except:
return str(strToEncode)
The error message I get is:
Traceback (most recent call last): File "XXX", line 106, in Query = ASPythonLib.RetrieveSQL(sqlFile, processedRecs), UnicodeEncodeError: ascii codec cant encode character u\u2026 in position 31: ordinal not in range(128)
the XXXX is just a file path to where this code is in our file system. Boss said I must remove the path.
I have also tried multiple variation of:
record['Description'] = record['Description'].encode('ascii', 'ignore').decode(encoding='ascii',errors='strict')
I have tried swapping the order of the encode and decode functions. I have tried different codecs and different error handling schemes.
****Edit**** This code works correct in like 20 other cycles so it's safe to assume the error is not in the RetrieveSQL().
Here is the code for RetrieveSQL:
def RetrieveSQL(SQLFile, VarList, Log = None):
SQLQuery = SQLFile.readline()
FileArgs = [""]
NumArgValues = len(VarList)
if( "{}" in SQLQuery ):
# NumFileArgs == 0
if (NumArgValues != 0):
print "Number of File Arguments is zero for File " + str(SQLFile) + " is NOT equal to the number of values provided per argument (" + str(NumArgValues) + ")."
return SQLFile.read()
elif( SQLQuery[0] != "{" ):
print "File " + str(SQLFile) + " is not an SQL source file."
return -1
elif( SQLQuery.startswith("{") ):
FileArgs = SQLQuery.replace("{", "").replace("}", "").split(", ")
for Arg in xrange(0, len(FileArgs)):
FileArgs[Arg] = "&" + FileArgs[Arg].replace("\n", "").replace("\t", "") + "&" # Add &'s for replacing
NumFileArgs = len(FileArgs)
if (NumFileArgs != NumArgValues):
if (NumArgValues == 0):
print "No values were supplied to RetrieveSQL() for File " + str(SQLFile) + " when there were supposed to be " + str(NumFileArgs) + " values."
return -1
elif (NumArgValues > 0):
"Number of File Arguments (" + str(NumFileArgs) + ") for File " + str(SQLFile) + " is NOT equal to the number of values provided per argument (" + str(NumArgValues) + ")."
return -1
SQLQuery = SQLFile.read()
VarList = list(VarList)
for Arg in xrange(0, len(FileArgs)):
if (VarList[Arg] == None):
SQLQuery = SQLQuery.replace(FileArgs[Arg], "NULL")
elif ("'" in str(VarList[Arg])):
SQLQuery = SQLQuery.replace(FileArgs[Arg], "'" + VarList[Arg].replace("'", "''") + "'")
elif ("&" in str(VarList[Arg])):
SQLQuery = SQLQuery.replace(FileArgs[Arg], "'" + VarList[Arg].replace("&", "&'||'") + "'")
elif (isinstance(VarList[Arg], basestring) == True):
VarList[Arg] = VarList[Arg].replace("'", "''")
SQLQuery = SQLQuery.replace(FileArgs[Arg], "'" + VarList[Arg] + "'")
else:
SQLQuery = SQLQuery.replace(FileArgs[Arg], str(VarList[Arg]))
SQLFile.seek(0)
return SQLQuery
****Edit #2 ****
Tried finding a complete traceback in logging files but the logging system for this script is terrible and never logs more than 'Cycle success' or 'Cycle Fail'. Ahh the fun of rewriting code written by people who don't know how to code.