Newbie in Python [2.7] function not working - python

I am using a script i've downloaded from the web to access our service API.
I am trying to run the function, but keep getting errors no matter what I am trying to do.
from PyBambooHR import PyBambooHR
bamboo = PyBambooHR(subdomain='domain', api_key='apicode')
changes = bamboo.get_employee_changes()
When I run this, I get the following error:
ValueError: Error: since argument must be a datetime.datetime instance
Now, no matter what I set as arguments, I still getting errors. I've also tried the syntax from: https://www.bamboohr.com/api/documentation/changes.php
The function is:
def get_employee_changes(self, since=None):
"""
Returns a list of dictionaries, each with id, action, and lastChanged keys, representing
the employee records that have changed since the datetime object passed in the since= argument.
#return List of dictionaries, each with id, action, and lastChanged keys.
"""
if not isinstance(since, datetime.datetime):
raise ValueError("Error: since argument must be a datetime.datetime instance")
url = self.base_url + 'employees/changed/'
params = {'since': since.strftime('%Y-%m-%dT%H:%M:%SZ')}
r = requests.get(url, params=params, headers=self.headers, auth=(self.api_key, ''))
r.raise_for_status()
return utils.transform_change_list(r.content)
Thanks for your help

As you see in that function is a parameter since of type datetime.datetime expected.
import datetime
changes = bamboo.get_employee_changes(since=datetime.datetime.now() - datetime.timedelta(days=365))
Should give you the changes since last year

Pass a variable of type datetime.datetime while calling the function bamboo.get_employee_changes()

Related

Cannot (always) fetch an attribute in an object even though it exists

I'm currently developing locally an Azure function that communicates with Microsoft Sentinel, in order to fetch the alert rules from it, and more specifically their respective querys :
credentials = AzureCliCredential()
alert_rules_operations = SecurityInsights(credentials, SUBSCRIPTION_ID).alert_rules
list_alert_rules = alert_rules_operations.list(resource_group_name=os.getenv('RESOURCE_GROUP_NAME'), workspace_name=os.getenv('WORKSPACE_NAME'))
The issue is that when I'm looping over list_alert_rules, and try to see each rule's query, I get an error:
Exception: AttributeError: 'FusionAlertRule' object has no attribute 'query'.
Yet, when I check their type via the type() function:
list_alert_rules = alert_rules_operations.list(resource_group_name=os.getenv(
'RESOURCE_GROUP_NAME'), workspace_name=os.getenv('WORKSPACE_NAME'))
for rule in list_alert_rules:
print(type(rule))
##console: <class 'azure.mgmt.securityinsight.models._models_py3.ScheduledAlertRule'>
The weirder issue is that this error appears only when you don't print the attribute. Let me show you:
Print:
for rule in list_alert_rules:
query = rule.query
print('query', query)
##console: query YAY I GET WHAT I WANT
No print:
for rule in list_alert_rules:
query = rule.query
...
##console: Exception: AttributeError: 'FusionAlertRule' object has no attribute 'query'.
I posted the issue on the GitHub repo, but I'm not sure whether it's a package bug or a runtime issue. Has anyone ran into this kind of problems?
BTW I'm running Python 3.10.8
TIA!
EDIT:
I've tried using a map function, same issue:
def format_list(rule):
query = rule.query
# print('query', query)
# query = query.split('\n')
# query = list(filter(lambda line: "//" not in line, query))
# query = '\n'.join(query)
return rule
def main(mytimer: func.TimerRequest) -> None:
# results = fetch_missing_data()
credentials = AzureCliCredential()
alert_rules_operations = SecurityInsights(
credentials, SUBSCRIPTION_ID).alert_rules
list_alert_rules = alert_rules_operations.list(resource_group_name=os.getenv(
'RESOURCE_GROUP_NAME'), workspace_name=os.getenv('WORKSPACE_NAME'))
list_alert_rules = list(map(format_list, list_alert_rules))
I have tried with same as you used After I changed like below; I get the valid response.
# Management Plane - Alert Rules
alertRules = mgmt_client.alert_rules.list_by_resource_group('<ResourceGroup>')
for rule in alertRules:
# Try this
test.query = rule.query //Get the result
#print(rule)
if mytimer.past_due:
logging.info('The timer is past due!')
Instead of this
for rule in list_alert_rules:
query = rule.query
Try below
for rule in list_alert_rules:
# Try this
test.query = rule.query
Sorry for the late answer as I've been under tons of work these last few days.
Python has an excellent method called hasattr that checks if the object contains a specific key.
I've used it in the following way:
for rule in rules:
if hasattr(rule, 'query'):
...
The reason behind using this is because the method returns object of different classes, however inherited from the one same mother class.
Hope this helps.

FastApi urls path and 2 values into a query

im using FastApi and get some troubles with url.
i have a root url
#app.get("/myurl")
http://host/myurl
and
http://host/myurl?id=2
and here function returns all info from needed table.
on url like http://host/myurl?id=2&type=3 i need to get another query from table. how i need to create function because now this http://host/myurl?id=2 overlapping this function http://host/myurl?id=2&type=3
how i can use multiple urls with different values in it in fastapi?
and i want to know how to make url like http://host/myurl?id=2&type=3,2 to return result from table for two types (query example is SELECT * from mytable WHERE id=%(id)s and type IN (1,2) but type IN (,) should be parameters which i need to inpout
how i can use multiple urls with different values in it in fastapi?
As far as I know, you can't. But fortunately, you don't need to. What you can do is define only one route ("/myurl") with both parameters id and type, and set the second as optional.
Then, if you don't receive type, you process a different query.
By the way, don't use id and type as parameter names, that will mess with the name of the in-built function id()and type().
Here a working example:
from fastapi import FastAPI, Query
app = FastAPI()
#app.get("/myurl")
async def my_url(my_id: int = Query(...), my_type: int = Query(None)):
if my_type:
return f"You gave an id ({my_id}) and a type ({my_type})."
return f"You gave only an id ({my_id}) but no type."
i want to know how to make url like http://host/myurl?id=2&type=3,2
Not sure you can do it at all. What you can do is add the type parameter several times, like this:
http://host/myurl?my_id=2&my_type=3&my_type=2
In this case, you need to slightly change your code:
from fastapi import FastAPI, Query
from typing import List
app = FastAPI()
#app.get("/myurl")
async def my_url(my_id: int = Query(...), my_type: List[int] = Query(None)):
if my_type:
if len(my_type) > 1:
return f"You gave an id ({my_id}) and a list of types ({my_type})."
else:
return f"You gave an id ({my_id}) and a type ({my_type})."
return f"You gave only an id ({my_id}) but no type."
Note that you'll always receive my_type as a list then, even if you pass it only one time.

Building URLs with concatinate

Trying to build a URL using the variables I've already setup and then a known part of the URL on the back end. The code will throw the following error:
TypeError: cannot concatenate 'str' and 'NoneType' objects
block_explorer_url = "https://blockexplorer.com/api/addrs/"
#?from=0&to=50
parser = argparse.ArgumentParser(description='Collect and visualize Bitcoin transactions and any related hidden services.')
parser.add_argument("--graph",help="Output filename of the graph file. Example: bitcoin.gexf",default="bitcoingraph.gexf")
parser.add_argument("--address", help="A bitcoin address to begin the search on.",)
args = parser.parse_args()
bitcoin_address = args.address
graph_file = args.graph
#
# Retrieve all bitcoin transactions for a Bitcoin address
#
def get_all_transactions(bitcoin_address):
transactions = []
from_number = 0
to_number = 50
block_explorer_url_full = block_explorer_url + bitcoin_address + "/txs?from=%d&to=%d" % (from_number,to_number)
Logically, having the variables there and then adding on the rest of the URL as a string makes since to me. Where am I going astray?
The problem is that when bitcoin_address is None (not provided by user), your program still tries to concatenate it to a str, which definitely won't work.
To solve that, you could add some code that checks the result of parse_args and raises an error when that happens, such as this:
if args.address is None:
raise ValueError('A bitcoin address must be provided.')
Separately, while your approach to string formatting is generally correct, you should consider moving away from C-style formatting and towards the format method, for example:
At the start of your script:
base_url = 'https://blockexplorer.com/api/addrs/{address}/txs?from={from}&to={to}'
And later in the function:
full_url = base_url.format(address=bitcoin_address,
from=from_number,
to=to_number)

Variable Route Not Working in For Loop

I tried to create multiple routes in one go by using the variables from the database and a for loop.
I tried this
temp = "example"
#app.route("/speaker/<temp>")
def getSpeakerAtr(temp):
return '''%s''' % temp
It works very well. BUT:
for x in models.Speaker.objects:
temp = str(x.name)
#app.route("/speaker/<temp>")
def getSpeakerAtr(temp):
return '''%s''' % temp
Doesn't work. The error message:
File "/Users/yang/Documents/CCPC-Website/venv/lib/python2.7/site-packages/flask/app.py", line 1013, in decorator
02:03:04 web.1 | self.add_url_rule(rule, endpoint, f, **options)
**The reason I want to use multiple routes is that I need to get the full data of an object by querying from the route. For example:
if we type this url:
//.../speaker/sam
we can get the object who has the 'name' value as 'sam'. Then I can use all of the values in this object like bio or something.**
You don't need multiple routes. Just one route that validates its value, eg:
#app.route('/speaker/<temp>')
def getSpeakerAtr(temp):
if not any(temp == str(x.name) for x in models.Speaker.objects):
# do something appropriate (404 or something?)
# carry on doing something else
Or as to your real intent:
#app.route('/speaker/<name>')
def getSpeakerAtr(name):
speaker = # do something with models.Speaker.objects to lookup `name`
if not speaker: # or whatever check is suitable to determine name didn't exist
# raise a 404, or whatever's suitable
# we have a speaker object, so use as appropriate

Passing a variable to a JSON web service

I am accessing the class from the code api_service.py, which can be found here. When I call the first function, I have no problem, because no variables are passed:
from api_service import ApiService
import json
def main():
api_key = *removed*
access_token = *removed*
calling = ApiService(api_key,access_token)
survey_list = calling.get_survey_list()
But when I use the same type of routine as above to call a function from ApiService that requires a variable, I'm told that I should pass an object.
survey_details = calling.get_survey_details("1234")
survey_details = json.loads(json.dumps(survey_details))
print survey_details
The specific error message:
{u'status': 3, u'errmsg': u"Value '1234' for field '_data' is not of type object"}
Details for the get_survey_details aspect of the SurveyMonkey API are here, although I think a python-guru can solve this without knowing about the API.
This is a javascript/json object:
{field:'value'}
You have passed a string which, doesn't count as an "object" for these purposes.
Note that the error message is being generated by the service you are accessing. This question would be better directed to the creator of the service.

Categories

Resources