making many to many relationships database in google app engine by python - python

Im trying to make 3 database; person, event and hobby. Each person selects hobbies from the list that is provided, which are in the hobby database. when a person creates a event, that person choose which hobby will be tagged to that event. From there event invitation will be send out to person who selected that hobby. And the event will be made using Google Calendar API....
im stuck on making this 3 database and trying to relate them using either relationalproperty or list property... looked around but not too good with programming so im kinda stuck...
if anyone could help me that would be really appreciated.
class Hobby(db.Model):
name = db.StringProperty()
#property
def members(self):
return Person.all().filter('hobby', self.key())
h1 = Hobby(key_name ='key1', name = 'tennis')
h2 = Hobby(name = 'basketball')
h1.put()
h2.put()
class Person(db.Model):
name = db.StringProperty()
hobby = db.ListProperty(db.Key)
p1 = Person(name = 'tom', hobby = Hobby.get_by_key_name(['key1']))
p1.put()
class Event(db.Model):
title = db.StringProperty(required=True)
description = db.TextProperty()
time = db.DateTimeProperty()
location = db.TextProperty()
creator = db.UserProperty()
edit_link = db.TextProperty()
gcal_event_link = db.TextProperty()
gcal_event_xml = db.TextProperty()
hobby = db.ListProperty(db.Key)
#property
def members(self):
return Person.all().filter('event', self.key())
class Attendee(db.Model):
email = db.StringProperty()
event = db.ReferenceProperty(Event)
hobby = db.ReferenceProperty(Hobby)
class Greeting(db.Model):
author = db.UserProperty()
content = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
class BasePage(webapp.RequestHandler):
title = ''
def write_page_header(self):
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('<html><head><title>%s</title>'
'<link href="static/invitations.css" rel="stylesheet" type="text/css"/>'
'</head><body><div id="main">' % (
self.title,))
self.write_signin_links()
def write_signin_links(self):
if users.get_current_user():
template_values = {
'signed_in': True,
'user_link': users.create_logout_url('/')}
else:
template_values = {
'signed_in': False,
'user_link': users.create_login_url('/events')}
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'signin.html')
self.response.out.write(template.render(path, template_values))
def write_page_footer(self):
self.response.out.write('</div></body></html>')
class StartPage(BasePage):
title = 'One Macnica'
def get(self):
self.write_page_header()
template_values = {'sign_in': users.create_login_url('/events')}
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'start.html')
self.response.out.write(template.render(path, template_values))
self.write_page_footer()
class EventsPage(BasePage):
title = 'One Macnica'
def __init__(self):
# Create a Google Calendar client to talk to the Google Calendar service.
self.calendar_client = gdata.calendar.service.CalendarService()
# Modify the client to search for auth tokens in the datastore and use
# urlfetch instead of httplib to make HTTP requests to Google Calendar.
gdata.alt.appengine.run_on_appengine(self.calendar_client)
def get(self):
"""Displays the events the user has created or is invited to."""
self.write_page_header()
# Find all events which this user has created, and find events which this
# user has been invited to.
invited_events = []
owned_events = []
token_request_url = None
# Find an AuthSub token in the current URL if we arrived at this page from
# an AuthSub redirect.
auth_token = gdata.auth.extract_auth_sub_token_from_url(self.request.uri)
if auth_token:
self.calendar_client.SetAuthSubToken(
self.calendar_client.upgrade_to_session_token(auth_token))
# Check to see if the app has permission to write to the user's
# Google Calendar.
if not isinstance(self.calendar_client.token_store.find_token(
'http://www.google.com/calendar/feeds/'),
gdata.auth.AuthSubToken):
token_request_url = gdata.auth.generate_auth_sub_url(self.request.uri,
('http://www.google.com/calendar/feeds/',))
query_time = self.request.get('start_time')
# TODO handle times provided in the URL.
if not query_time:
query_time = datetime.datetime.now()
# Find the events which were created by this user, and those which the user
# is invited to.
if users.get_current_user():
owned_query = Event.gql('WHERE creator = :1 ORDER BY time',
users.get_current_user())
owned_events = owned_query.fetch(5)
invited_query = Attendee.gql('WHERE email = :1',
users.get_current_user().email())
for invitation in invited_query.fetch(5):
try:
invited_events.append(invitation.event)
except db.Error, message:
if message[0] == 'ReferenceProperty failed to be resolved':
# The invitee has an invitation to an event which no longer exists.
pass
else:
raise
template_values = {
'token_request_url': token_request_url,
'owned_events': owned_events,
'invited_events': invited_events,
}
# Display the events.
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'events.html')
self.response.out.write(template.render(path, template_values))
self.write_page_footer()
def post(self):
"""Adds an event to Google Calendar."""
event_id = self.request.get('event_id')
# Fetch the event from the datastore and make sure that the current user
# is an owner since only event owners are allowed to create a calendar
# event.
event = Event.get_by_id(long(event_id))
if users.get_current_user() == event.creator:
# Create a new Google Calendar event.
event_entry = gdata.calendar.CalendarEventEntry()
event_entry.title = atom.Title(text=event.title)
event_entry.content = atom.Content(text=event.description)
if start_time is None:
start_time = '%s.000Z' % event.time.isoformat()
end_time = '%s.000Z' % event.time.isoformat(time.time()+3600)
event_entry.when.append(gdata.calendar.When(start_time=start_time, end_time=end_time))
event_entry.where.append(
gdata.calendar.Where(value_string=event.location))
# Add a who element for each attendee.
attendee_list = event.attendee_set
if attendee_list:
for attendee in attendee_list:
new_attendee = gdata.calendar.Who()
new_attendee.email = attendee.email
event_entry.who.append(new_attendee)
#Adding hobby for each attendee
"""hobby_list = event.hobby_set
if hobby_list:
for hobby in hobby_list:
new_hobby = gdata.calendar.ExtendedProperty()
new_hobby.name = hobby.name
event_entry.extended_property.append(new_hobby)
"""
# Hobby to which a person belongs:
p = db.get(person_key)
hobby = db.get(p.hobby) #batch get using list of keys
for hobby in hobby:
new_hobby = gdata.calendar.ExtendedProperty()
new_hobby = hobby.name
event_entry.extended_property.append(new_hobby)
#Person that belong to a hobby:
h = db.get(hobby_key)
for person in h.members:
new_person = gdata.calendar.Who()
new_person.name = person.name
event_entry.who.append(new_person)
# Event to which a person belongs:
p = db.get(person_key)
event = db.get(p.event)
for event in event:
new_event = gdata.calendar.ExtendedProperty()
new_event = event.title
event_entry.extended_property.append(new_event)
# Person that belong to a event:
e = db.get(event_key)
for person in e.members:
new_person = gdata.calendar.Who()
new_person.name = person.name
event_entry.who.append(new_person)
# Send the event information to Google Calendar and receive a
# Google Calendar event.
try:
cal_event = self.calendar_client.InsertEvent(event_entry,
'http://www.google.com/calendar/feeds/default/private/full')
edit_link = cal_event.GetEditLink()
if edit_link and edit_link.href:
# Add the edit link to the Calendar event to use for making changes.
event.edit_link = edit_link.href
alternate_link = cal_event.GetHtmlLink()
if alternate_link and alternate_link.href:
# Add a link to the event in the Google Calendar HTML web UI.
event.gcal_event_link = alternate_link.href
event.gcal_event_xml = str(cal_event)
event.put()
# If adding the event to Google Calendar failed due to a bad auth token,
# remove the user's auth tokens from the datastore so that they can
# request a new one.
except gdata.service.RequestError, request_exception:
request_error = request_exception[0]
if request_error['status'] == 401 or request_error['status'] == 403:
gdata.alt.appengine.save_auth_tokens({})
# If the request failure was not due to a bad auth token, reraise the
# exception for handling elsewhere.
else:
raise
else:
self.response.out.write('I\'m sorry, you don\'t have permission to add'
' this event to Google Calendar.')
# Display the list of events also as if this were a get.
self.get()
I have posted some of my code. I have edit event class and such after this but i guess its not that important in solving the database situation...
thanks in advance for any help or advice.

Your problem with creating a Person entity is that above (at p1) you're trying to assign a Hobby entity to Person.hobby which should be a list of Hobby keys (and probably be named hobbies)
h = Hobby(name='basketball')
h_key = h.put() # or after h.put(), h.key()
p = Person(name='tom', hobbies=[h_key])
p.put()
Also, your Person model has no property event so Event.members will fail.
Other than these, using db.ListProperty() is the correct way to handle many to many relationships which carry no additional information.

Related

Django manytomany field holding Users autofilling

I am pulling data from a json file on the web, and updating it in my django database. I want to keep track of users that are associated with each team, but as soon as a user loads the page once they are added to the model. How do I avoid this?
class Team(models.Model):
name = models.CharField(max_length=120)
abbreviation = models.CharField(max_length=3)
id = models.IntegerField(primary_key=True)
link = models.CharField(max_length=120)
wins = models.IntegerField(default=0)
losses = models.IntegerField(default=0)
ties = models.IntegerField(default=0)
points = models.IntegerField(default=0)
users = models.ManyToManyField(User)
def getTeams():
import requests
baseUrl = "https://statsapi.web.nhl.com/"
# INITALIZING THE DATA IN THE DATA DICTIONARY
r = requests.get(baseUrl + '/api/v1/teams')
originalData = r.json()
# i dont need the copyright, only care about the teams
originalData = originalData["teams"]
for team in originalData:
id = team["id"]
try:
databaseTeam = Team.objects.get(id = id)
except Exception:
Team.objects.create(id = id)
databaseTeam = Team.objects.get(id = id)
databaseTeam.name = team["name"]
databaseTeam.abbreviation = team["abbreviation"]
databaseTeam.link = team["link"]
databaseTeam.save()
print("done")
#login_required
def myTeamView(request):
t1 = Thread(target=getTeams)
t1.start()
return(render(request, "teams/myTeams.html", {}))
The user is stored on user variable inside the request, so first we need to pass it to getTeams method. Then we use the method add of Manytomany fields to append an record to it, in this case the user.
def getTeams(request):
import requests
baseUrl = "https://statsapi.web.nhl.com/"
# INITALIZING THE DATA IN THE DATA DICTIONARY
r = requests.get(baseUrl + '/api/v1/teams')
originalData = r.json()
# i dont need the copyright, only care about the teams
originalData = originalData["teams"]
for team in originalData:
id = team["id"]
try:
databaseTeam = Team.objects.get(id = id)
except Exception:
Team.objects.create(id = id)
databaseTeam = Team.objects.get(id = id)
databaseTeam.name = team["name"]
databaseTeam.abbreviation = team["abbreviation"]
databaseTeam.link = team["link"]
databaseTeam.save()
databaseTeam.users.add(request.user) # after save!!
print("done")
#login_required
def myTeamView(request):
t1 = Thread(target=getTeams, args=(request, ))
t1.start()
return(render(request, "teams/myTeams.html", {}))

Lambda function acting very strange only when I call the Lex bot

I have an app with the following flow:
Placed a phone call or use the chat UI to invoke a Lex bot via Get Customer Input block in Amazon Connect
The Lex bot asks for some information from the customer such as Name, company you're calling from, who referred you, and the product you're calling aobut.
The Lex bot is based on the order flowers sample and invokes a Lambda function with the salesforce API imported as a layer. The purpose of the SalesForce layer is to check if the caller is an existing contact in SalesForce and to check if the company they are calling from exists or not. If neither is true, then the Lambda function creates new records in SalesForce.
Once the bot understands what the customer is calling about it then places an outbound call to the customer using the phone number in their contact record in SalesForce, unless they don't have one, at which point it asks for their phone number and then places an outbound call to the customer and connects to an agent.
Whenever I use the Chat UI for this flow it works perfectly every time with no issues. However, ever few phone call I place I get something very weird happening. I'm able to get the system to recognize and repeat my name, the company I'm calling from, and the company who referred me every time. But when it breaks, it breaks at the spot where it asks me for the product I'm calling about. I tell it "I'm calling about air filters" and the system says "Hi Hersal Thomas, can you tell me which company you're contacting us from?" and I speak "Facebook" and it understands me and goes to the same point to where it asks me which product I'm inquiring about and when I speak "air filters" it loops back to the previous step where it says "Hi Hersal Thomas, can you tell me which company you're contacting us from?" It does this three times and then eventually connects my call to an agent.
Could there be a weird loop in the Lambda function that is causing this behavior?
Here is the Python 3.6 function:
"""
This sample demonstrates an implementation of the Lex Code Hook Interface
in order to serve a sample bot which manages orders for flowers.
Bot, Intent, and Slot models which are compatible with this sample can be found in the Lex Console
as part of the 'OrderFlowers' template.
For instructions on how to set up and test this bot, as well as additional samples,
visit the Lex Getting Started documentation http://docs.aws.amazon.com/lex/latest/dg/getting-started.html.
"""
import math
import dateutil.parser
import datetime
import calendar
import time
import os
import logging
import json
from salesforce_api import Salesforce
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
""" --- Helpers to build responses which match the structure of the necessary dialog actions --- """
def get_slots(intent_request):
return intent_request['currentIntent']['slots']
def elicit_slot(session_attributes, intent_name, slots, slot_to_elicit, message):
return {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'ElicitSlot',
'intentName': intent_name,
'slots': slots,
'slotToElicit': slot_to_elicit,
'message': {
"contentType": "PlainText",
"content": message
}
}
}
def close(session_attributes, fulfillment_state, message):
response = {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'Close',
'fulfillmentState': fulfillment_state,
'message': message
}
}
return response
def delegate(session_attributes, slots):
return {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'Delegate',
'slots': slots
}
}
""" --- Helper Functions --- """
def parse_int(n):
try:
return int(n)
except ValueError:
return float('nan')
def build_validation_result(is_valid, violated_slot, message_content):
if message_content is None:
return {
"isValid": is_valid,
"violatedSlot": violated_slot,
}
return {
'isValid': is_valid,
'violatedSlot': violated_slot,
'message': {'contentType': 'PlainText', 'content': message_content}
}
def isvalid_date(date):
try:
dateutil.parser.parse(date)
return True
except ValueError:
return False
def validate_user_informations(full_name, company, refered_from, product):
flower_types = ['lilies', 'roses', 'tulips']
if flower_type is not None and flower_type.lower() not in flower_types:
return build_validation_result(False,
'FlowerType',
'We do not have {}, would you like a different type of flower? '
'Our most popular flowers are roses'.format(flower_type))
if date is not None:
if not isvalid_date(date):
return build_validation_result(False, 'PickupDate', 'I did not understand that, what date would you like to pick the flowers up?')
elif datetime.datetime.strptime(date, '%Y-%m-%d').date() <= datetime.date.today():
return build_validation_result(False, 'PickupDate', 'You can pick up the flowers from tomorrow onwards. What day would you like to pick them up?')
if pickup_time is not None:
if len(pickup_time) != 5:
# Not a valid time; use a prompt defined on the build-time model.
return build_validation_result(False, 'PickupTime', None)
hour, minute = pickup_time.split(':')
hour = parse_int(hour)
minute = parse_int(minute)
if math.isnan(hour) or math.isnan(minute):
# Not a valid time; use a prompt defined on the build-time model.
return build_validation_result(False, 'PickupTime', None)
if hour < 10 or hour > 16:
# Outside of business hours
return build_validation_result(False, 'PickupTime', 'Our business hours are from ten a m. to five p m. Can you specify a time during this range?')
return build_validation_result(True, None, None)
def add_months(sourcedate, months):
month = sourcedate.month - 1 + months
year = sourcedate.year + month // 12
month = month % 12 + 1
day = min(sourcedate.day, calendar.monthrange(year,month)[1])
return datetime.date(year, month, day)
def convertNumberToE164(number):
number = number.replace(' ', '')
number = number.replace('+', '')
number = number.replace('(', '')
number = number.replace(')', '')
number = number.replace('-', '')
if len(number) == 10:
number = '+1{}'.format(number)
else:
number = '+{}'.format(number)
return number
""" --- Functions that control the bot's behavior --- """
def get_customer_information(intent_request):
"""
Performs dialog management and fulfillment for ordering flowers.
Beyond fulfillment, the implementation of this intent demonstrates the use of the elicitSlot dialog action
in slot validation and re-prompting.
"""
logger.debug("event: ==================")
logger.debug(json.dumps(intent_request))
full_name = get_slots(intent_request)["full_name"]
company = get_slots(intent_request)["company"]
refered_from = get_slots(intent_request)["refered_from"]
product = get_slots(intent_request)["product"]
phone_number = get_slots(intent_request)["phone_number"]
agree_phone_call = get_slots(intent_request)["agree_phone_call"]
source = intent_request['invocationSource']
if source == 'DialogCodeHook':
# Perform basic validation on the supplied input slots.
# Use the elicitSlot dialog action to re-prompt for the first violation detected.
slots = get_slots(intent_request)
output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
# validation_result = validate_user_informations(full_name, company, refered_from, product)
# if not validation_result['isValid']:
# slots[validation_result['violatedSlot']] = None
# return elicit_slot(intent_request['sessionAttributes'],
# intent_request['currentIntent']['name'],
# slots,
# validation_result['violatedSlot'],
# validation_result['message'])
if full_name is not None and company is not None and refered_from is not None and product is not None:
if intent_request['currentIntent']['name'] == 'VoiceOmniIntent' and ('connect_channel' in output_session_attributes and output_session_attributes['connect_channel'] is not None and output_session_attributes['connect_channel'] == "VOICE"):
#if incoming from Voice
client = Salesforce(
username=os.environ['sales_username'],
password=os.environ['sales_password'],
security_token=os.environ['sales_token']
)
accounts = client.sobjects.query("SELECT Id, name, phone FROM Account where name = '{}'".format(company))
account_id = -1
if len(accounts) > 0:
account_id = accounts[0]['Id']
else:
acc_info = client.sobjects.Account.insert({'name': company})
account_id = acc_info['id']
full_name = full_name.title()
contacts = client.sobjects.query("SELECT Id, name, phone, accountid from Contact where name='{}' and accountid='{}'".format(full_name, account_id))
if len(contacts) > 0:
client.sobjects.Contact.update(contacts[0]['Id'], {'phone': convertNumberToE164(output_session_attributes['phone_number'])})
output_session_attributes['contact_id'] = contacts[0]['Id']
else:
name_arr = full_name.split(' ')
first_name = name_arr[0] if len(name_arr) > 1 else ''
last_name = name_arr[0] if len(name_arr) == 1 else name_arr[1]
contact_res = client.sobjects.Contact.insert({'firstname': first_name, 'lastname': last_name, 'phone': convertNumberToE164(output_session_attributes['phone_number']), 'accountid': account_id})
output_session_attributes['contact_id'] = contact_res['id']
today_date = datetime.date.today()
close_date = add_months(today_date, 1)
close_date = close_date.strftime('%Y-%m-%d')
opp_info = client.sobjects.Opportunity.insert({'name': product, 'closedate': close_date, 'stagename': 'Qualification', 'accountid': account_id})
return delegate(output_session_attributes, get_slots(intent_request))
else:
#if incoming from Chat
if phone_number is not None:
#once customer fills his phone_number
client = Salesforce(
username=os.environ['sales_username'],
password=os.environ['sales_password'],
security_token=os.environ['sales_token']
)
accounts = client.sobjects.query("SELECT Id, name, phone FROM Account where name = '{}'".format(company))
if len(accounts) > 0:
account_id = accounts[0]['Id']
full_name = full_name.title()
contacts = client.sobjects.query("SELECT Id, name, phone, accountid from Contact where name='{}' and accountid='{}'".format(full_name, account_id))
if len(contacts) > 0:
client.sobjects.Contact.update(contacts[0]['Id'], {'phone': convertNumberToE164(phone_number)})
output_session_attributes['contact_id'] = contacts[0]['Id']
else:
name_arr = full_name.split(' ')
first_name = name_arr[0] if len(name_arr) > 1 else ''
last_name = name_arr[0] if len(name_arr) == 1 else name_arr[1]
contact_res = client.sobjects.Contact.insert({'firstname': first_name, 'lastname': last_name, 'phone': convertNumberToE164(phone_number), 'accountid': account_id})
output_session_attributes['contact_id'] = contact_res['id']
output_session_attributes['phone_number'] = convertNumberToE164(phone_number)
return delegate(output_session_attributes, get_slots(intent_request))
elif agree_phone_call is not None:
#once his company and phone_number are exist
if agree_phone_call.lower() == 'yes':
#if he agreed to phone call to his number
phone_number = convertNumberToE164(output_session_attributes['phone_number']) if ('phone_number' in output_session_attributes and output_session_attributes['phone_number'] is not None) else ''
return delegate(output_session_attributes, get_slots(intent_request))
else:
#asking his phone number
return elicit_slot(output_session_attributes,
intent_request['currentIntent']['name'],
slots,
"phone_number",
"What number would you like us to call you at?")
else:
#once customer fills full_name, company, refered_from, product
client = Salesforce(
username=os.environ['sales_username'],
password=os.environ['sales_password'],
security_token=os.environ['sales_token']
)
accounts = client.sobjects.query("SELECT Id, name, phone FROM Account where name = '{}'".format(company))
if len(accounts) > 0:
inserted_id = accounts[0]['Id']
contacts = client.sobjects.query("SELECT Id, name, phone, accountid from Contact where name='{}' and accountid='{}'".format(full_name, inserted_id))
today_date = datetime.date.today()
close_date = add_months(today_date, 1)
close_date = close_date.strftime('%Y-%m-%d')
opp_info = client.sobjects.Opportunity.insert({'name': product, 'closedate': close_date, 'stagename': 'Qualification', 'accountid': inserted_id})
if len(contacts) > 0 and contacts[0]['Phone'] is not None:
output_session_attributes['phone_number'] = convertNumberToE164(contacts[0]['Phone'])
output_session_attributes['contact_id'] = contacts[0]['Id']
return elicit_slot(output_session_attributes,
intent_request['currentIntent']['name'],
slots,
"agree_phone_call",
"I see that you’re a customer of ACME Manufacturing. Can we call you at {}? (Yes/No)".format(convertNumberToE164(contacts[0]['Phone'])))
logger.debug("{}\'s phone number is {}".format(full_name, convertNumberToE164(contacts[0]['phone'])))
else:
return elicit_slot(output_session_attributes,
intent_request['currentIntent']['name'],
slots,
"phone_number",
"What number would you like us to call you at?")
else:
acc_info = client.sobjects.Account.insert({'name': company})
inserted_id = acc_info['id']
today_date = datetime.date.today()
close_date = add_months(today_date, 1)
close_date = close_date.strftime('%Y-%m-%d')
logger.debug(close_date)
opp_info = client.sobjects.Opportunity.insert({'name': product, 'closedate': close_date, 'stagename': 'Qualification', 'accountid': inserted_id})
return elicit_slot(output_session_attributes,
intent_request['currentIntent']['name'],
slots,
"phone_number",
"What number would you like us to call you at?")
# Pass the price of the flowers back through session attributes to be used in various prompts defined
# on the bot model.
# if flower_type is not None:
# output_session_attributes['Price'] = len(flower_type) * 5 # Elegant pricing model
return delegate(output_session_attributes, get_slots(intent_request))
# Order the flowers, and rely on the goodbye message of the bot to define the message to the end user.
# In a real bot, this would likely involve a call to a backend service.
output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
if intent_request['currentIntent']['name'] == 'VoiceOmniIntent' and ('connect_channel' in output_session_attributes and output_session_attributes['connect_channel'] is not None and output_session_attributes['connect_channel'] == "VOICE"):
output_session_attributes['full_name'] = full_name.title()
output_session_attributes['company'] = company
output_session_attributes['refered_from'] = refered_from
output_session_attributes['product'] = product
return close(output_session_attributes,
'Fulfilled',
{'contentType': 'PlainText',
'content': 'Thanks {}, we will connect you with our agent now.'.format(full_name)})
else:
output_session_attributes['full_name'] = full_name
output_session_attributes['company'] = company
output_session_attributes['refered_from'] = refered_from
output_session_attributes['product'] = product
output_session_attributes['phone_number'] = convertNumberToE164(phone_number)
return close(output_session_attributes,
'Fulfilled',
{'contentType': 'PlainText',
'content': 'Okay, our agent will call you shortly. Thanks.'})
""" --- Intents --- """
def dispatch(intent_request):
"""
Called when the user specifies an intent for this bot.
"""
logger.debug('dispatch userId={}, intentName={}'.format(intent_request['userId'], intent_request['currentIntent']['name']))
intent_name = intent_request['currentIntent']['name']
# Dispatch to your bot's intent handlers
if intent_name == 'VoiceOmniIntent' or intent_name == 'ChatOmniIntent':
return get_customer_information(intent_request)
raise Exception('Intent with name ' + intent_name + ' not supported')
""" --- Main handler --- """
def lambda_handler(event, context):
"""
Route the incoming request based on intent.
The JSON body of the request is provided in the event slot.
"""
# By default, treat the user request as coming from the America/New_York time zone.
os.environ['TZ'] = 'America/New_York'
time.tzset()
logger.debug(json.dumps(event))
logger.debug('event.bot.name={}'.format(event['bot']['name']))
# return event
return dispatch(event)

How to make multiple buttons in Flask process them in separate way?

I'm creating my very first web app with Flask. It must connect to MySQL (table called "Tasks") with SQLAlchemy and after that output all tasks from this table. All "tasks" have fields "StartDevelop" and "FinishDevelop" (DateTime fields). So my task is to output two buttons next to every name of "task". They must work with MySQL and send current time.
How can I connect two buttons to every row and connect all of them to python's script?
Example:
task1(string), AcceptTask1(button), CompleteTask1(button)
task2(string), AcceptTask2(button), CompleteTask2(button)
task3(string), AcceptTask3(button), CompleteTask3(button)
task4(string), AcceptTask4(button), CompleteTask4(button)
...
where number of tasks is accepted from datebase.
Code I made
I made dictionary, where key is task.Id and value is form(with string fields and two buttons). I also using field.descriptions to output/not output them.
#app.route('/database', methods=['GET','POST'])
#login_required
def database():
page = request.args.get('page', 1, type=int)
tasks = Tasks.query.filter(current_user.Id == Tasks.Developer or current_user.Id == Tasks.Reviewer).paginate(page, app.config['TASKS_PER_PAGE'], False)
forms = dict()
for task in tasks.items:
forms[task.Id] = DataBaseForm()
forms[task.Id].set_values(task,current_user)
class DataBaseForm(FlaskForm):
eord = StringField()
task = StringField()
assign_date = DateTimeField()
type = StringField()
accept_date = DateTimeField()
accepted = SubmitField(label = 'Submit', description = 'Submit')
comment = StringField()
completed = SubmitField(label = 'Submit', description = None)
def set_values(self, task, user):
self.eord.description = task.course.Name
self.task.description = task.Name
self.assign_date.description = task.Created
if (user.Id == task.Developer):
if(task.EndDevelop):
self.accept_date.description = task.EndDevelop
self.accepted.description = ""
else:
self.accepted.description = 'Submit'
self.comment.description = 'Comment'
if (user.Id == task.Reviewer):
if(task.EndReview):
self.accept_date.description = task.EndReview
self.accepted.description = ""
else:
self.accepted.description = 'Submit'
self.comment.description = 'Comment'
if(task.EndReview and task.EndDevelop):
self.completed.description = 'Complete'

Python - Create/Read/Update/Delete records in NetSuite

I was wondering how to Create/Read/Update/Delete records and their standard/custom fields, using python SOAP with NS WSDL
Here's a script that gives an example on how to login, and then to CRUD the records in NetSuite.
from zeep import Client
WSDL_URL = 'https://webservices.netsuite.com/wsdl/v2017_2_0/netsuite.wsdl' #WSDL we're using (don't change)
NS_EMAIL= 'NSemail#email.com' #NS-Email
NS_PASSWORD = 'NSPassword' #NS-Password
NS_ROLE = 'NSroleId' #NS-Role Id
NS_ACCOUNT = 'NSaccountId' #NS-Account Id
NS_APPID = 'NS268FD3-8553-4464-AEEB-FB6BE2EE616E' #NS App-ID
def make_app_info(client): #make app info, used in login_client
AppInfo = client.get_type('ns4:ApplicationInfo')
app_info = AppInfo(applicationId = NS_APPID)
return app_info
def make_passport(client): #make passport, used in login_client
RecordRef = client.get_type('ns0:RecordRef')
Passport = client.get_type('ns0:Passport')
role = RecordRef(internalId=NS_ROLE)
return Passport(email=NS_EMAIL,
password=NS_PASSWORD,
account=NS_ACCOUNT,
role=role)
def login_client(): #login
client = Client(WSDL_URL)
login = client.service.login(passport=make_passport(client), _soapheaders={'applicationInfo': make_app_info(client)}, )
return client
def add_customer(): #add a customer, example
client = login_client()
RecordRef = client.get_type('ns0:RecordRef') #set RecordRef as a RecordReference
StringCustomFieldRef = client.get_type('ns0:StringCustomFieldRef') #custom string field ref
CustomFieldList = client.get_type('ns0:CustomFieldList') #translator for custom field list
#customField acctName
acctName = StringCustomFieldRef() #this custom field is a string
acctName.internalID = '1569'
acctName.scriptId = 'custentity_sf_account_name'
acctName.value = 'Test data'
#customField acctId
acctID= StringCustomFieldRef()
acctID.internalId= '1596'
acctID.scriptId= 'custentity_account_id'
acctID.value = 'More Test data'
Customer = client.get_type('ns13:Customer') #make customer of type Customer
customer = Customer( #set customer
companyName='TEST',
entityId='TEST (US LLC)',
subsidiary = RecordRef(internalId='5', type='subsidiary'), #subsidiary is a RecordRef field, so you need to use RecordRef
customFieldList = CustomFieldList([acctID,acctName]) #set custom Fields
)
response = client.service.add(customer) #make the call
print(response)
def get_customer(id): #fetch customer
client = login_client()
Record = client.get_type('ns0:RecordRef') #set Record = to RecordReference
record = Record(internalId=id, type='customer') #change type for different type searches
response = client.service.get(record)
r = response.body.readResponse
#print(r) #detailed view
if r.status.isSuccess:
print(r.record) #r.record.companyName #simple view
def update_customer(): #update a customer
client = login_client()
Customer = client.get_type('ns13:Customer') #set Customer = to NS customer type
customer = Customer(
internalId = '451348', #must specify internalId
companyName='Testing 123'
)
response = client.service.update(customer) #upsert can also be used
print(response)
def delete_customer(id): #delete
client = login_client()
Record = client.get_type('ns0:RecordRef') #set Record to RecordReference
record = Record(internalId=id, type='customer')
response = client.service.delete(record) #run command
print(response)
def add_order(): #add an order
client = login_client()
RecordRef = client.get_type('ns0:RecordRef')
SelectCustomFieldRef = client.get_type('ns0:SelectCustomFieldRef')
StringCustomFieldRef = client.get_type('ns0:StringCustomFieldRef')
CustomFieldList = client.get_type('ns0:CustomFieldList')
SalesOrderItemList = client.get_type('ns19:SalesOrderItemList')
Order = client.get_type('ns19:SalesOrder')
SalesOrderItem = client.get_type('ns19:SalesOrderItem')
billtier = SelectCustomFieldRef() #using SelectCustomFieldRef since custom field is a select
billtier.internalId = '308' #custField InternalId
billtier.scriptId = 'custbody_bill_to_tier' #custField scriptId
billtier.value ={
'internalId': '2', #option ID
'externalId': None,
'typeId': '12' #list Id
}
item1 = SalesOrderItem() #making a single lineitem
item1.quantity = '1'
item1.item = RecordRef(internalId='5816')
item1.amount = 999
order = Order(
entity = RecordRef(internalId='451656', type='customer'),
itemList= SalesOrderItemList([item1]), #Add the line item
customFieldList = CustomFieldList([billtier]) #add the custom fields
)
response = client.service.add(order) #add the order
print(response)
Some Notes:
In cases where it says: RecordRef = client.get_type('ns0:RecordRef')
the ns0 refers to the namespace .xsd file that is in the import section on the wsdl.
A list of all NetSuite objects and their fields can be found here: http://www.netsuite.com/help/helpcenter/en_US/srbrowser/Browser2016_1/schema/other/salesorderitemlist.html?mode=package
Details about field references to use when handling different types of custom fields:
https://system.na1.netsuite.com/app/help/helpcenter.nl?fid=section_n3458179.html

need help creating permalinks in google app engine

So I am trying to create a unique permalink each time that a person posts on my webpage and I want it to be relatively search engine friendly so I have made a little code to change the title to a good search engine title and it is working but then my handler cannot accept it. At least that is what I think is happening because the webpage just gives me a 404 error. The HTML works fine because when I redirect to a static page it all goes through. Here is the applicable code:
def post(self):
subject = self.request.get('subject')
content = self.request.get('content')
if subject and content:
p = Post(parent = blog_key(), subject = subject, content = content)
p.put()
id=str(p.key().id())
subject = str(subject)
subject = subject.replace(' ', '25fdsa67ggggsd5')
subject = ''.join(e for e in subject if e.isalnum())
subject = subject.replace('25fdsa67ggggsd5', '-')
subject = subject.lower()
url = '/blog/%s/%s' % (id, subject)
self.redirect('/blog/%s/%s' % (id, subject))
class PostPage(BlogHandler):
def get(self, post_id):
key = db.Key.from_path('PersonalPost', int(post_id), parent=blog_key())
post = db.get(key)
if not post:
self.error(404)
return
self.render("permalink.html", post = post)
class PersonalPost(db.Model):
subject = db.StringProperty(required = True)
content = db.TextProperty(required = True)
created = db.DateTimeProperty(auto_now_add = True)
last_modified = db.DateTimeProperty(auto_now = True)
user_id = db.StringProperty(required = True)
def render(self):
self._render_text = self.content.replace('\n', '<br>')
return render_str("post.html", p = self)
def blog_key(name = 'default'):
return db.Key.from_path('blogs', name)
app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
And again it works when I just have it redirect to the main page and list them but not when I try to direct to the new SEO page.
UPDATE:
The test url I am using is setting
subject = "test-url"
id = "1234"
The app then directs me to www.url.com/blog/1234/test-url but it gives me a 404 error.
You define two groups in ('/blog/([0-9]+)/([.*]+) but your PostPage.get() only takes one.
Change it to def get(self, post_id, subject) or remove the second group ('/blog/([0-9]+)/[.*]+
I think you should have a look at the quotes on ur handler mapping, it seems inconsistent.
yours: app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
try : app = webapp2.WSGIApplication(['/blog/([0-9]+)/([.*]+)', PostPage)]

Categories

Resources