FLASK-ADDING DATETIME CALCULATION INTO DATABASE - datetime

I m trying to perform a little calculation and Logic on date.time with Flask application.
1.) the application will calculate the difference between issue date and expiry date called "remaining days" , The application will check if remaining days is less than 365 days and trigger a function
I attempted the first logic to manipulate the data and submit to database
`#bp.route('/cerpacs/add', methods=['GET', 'POST'])
#login_required
def add_cerpac():
"""
Add a an Cerpac/ expartriates to the database
"""
check_admin()
add_cerpac = True
form =CerpacForm()
if form.validate_on_submit():
cerpac = Cerpac(cerpac_serial_no=form.cerpac_serial_no.data,
cerpac_issue_date= form.cerpac_issue_date.data,
cerpac_exp_date=form.cerpac_exp_date.data,
employee =form.employee.data, )
form.cerpac_issue_date.data = cerpac.cerpac_issue_date
form.cerpac_exp_date.data = cerpac.cerpac_exp_date
if request.method == 'POST':
todays_date = datetime.now()
t = cerpac.cerpac_issue_date
t1 = cerpac.cerpac_exp_date
remaining_days = t1 - t
print(remaining_days) - good prints my result!
remaining_days = cerpac.remaining_days ----not adding to database
try:
add cerpac to the database
db.session.add(cerpac)
db.session.commit()
flash('You have successfully added a Cerpac.' )`
`
my model:
class Cerpac(db.Model):
__tablename__ = 'cerpacs'
id = db.Column(db.Integer, primary_key=True)
cerpac_issue_date = db.Column(db.DateTime)
cerpac_exp_date=db.Column(db.DateTime)
remaining_days = db.Column(db.DateTime)
cerpac_serial_no = db.Column(db.String(60))
cerpac_upload = db.Column(db.String(20), default='cerpac.jpg')
renew_status = db.Column(db.Boolean, default=False)
process_status = db.Column(db.Boolean, default=False)
renewcerpac_id = db.Column(db.Integer, db.ForeignKey('renewcerpacs.id'))
employee_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
def __repr__(self):
return '<Cerpac {}>'.format(self.name) model:
I want to add this to database and eventually write a function like this:
I had a mistake also in the code because I had error issue_date not defined. How do I define issue_date as a date.time variable?
def remaining_days(issue_date, expired_date):
issue_date = datetime(issue_date)
days_to_go = expired - issue
if days_to_go == 365:
renew_status== True
print("time to renew")
print("We are Ok")

I would simplify this to something like:
from datetime import datetime
class Cerpac(db.Model):
...
cerpac_exp_date=db.Column(db.DateTime)
...
#property
def remaining_days(self):
return (self.cerpac_exp_date - self.cerpac_issue_date).days
#property
def days_to_expiry(self):
return (self.cerpac_exp_date - datetime.now()).days
Then, days_to_expiry and remaining_days become properties calculated when you query, and update automatically when they renew their cards.

Related

Access the contents of the row inserted into Dynamodb using Pynamodb save method

I have the below model for a my dynamodb table using pynamodb :
from pynamodb.models import Model
from pynamodb.attributes import (
UnicodeAttribute, UTCDateTimeAttribute, UnicodeSetAttribute, BooleanAttribute
)
class Reminders(Model):
"""Model class for the Reminders table."""
# Information on global secondary index for the table
# user_id (hash key) + reminder_id+reminder_title(sort key)
class Meta:
table_name = 'Reminders'
region = 'eu-central-1'
reminder_id = UnicodeAttribute(hash_key=True)
user_id = UnicodeAttribute(range_key=True)
reminder_title = UnicodeAttribute()
reminder_tags = UnicodeSetAttribute()
reminder_description = UnicodeAttribute()
reminder_frequency = UnicodeAttribute(default='Only once')
reminder_tasks = UnicodeSetAttribute(default=set())
reminder_expiration_date_time = UTCDateTimeAttribute(null=True)
reminder_title_reminder_id = UnicodeAttribute()
next_reminder_date_time = UTCDateTimeAttribute()
should_expire = BooleanAttribute()
When i want to create a new reminder i do it through the below code :
class DynamoBackend:
#staticmethod
def create_a_new_reminder(new_reminder: NewReminder) -> Dict[str, Any]:
"""Create a new reminder using pynamodb."""
new_reminder = models.Reminders(**new_reminder.dict())
return new_reminder.save()
In this case the NewReminder is an instance of pydantic base model like so :
class NewReminder(pydantic.BaseModel):
reminder_id: str
user_id: str
reminder_title: str
reminder_description: str
reminder_tags: Sequence[str]
reminder_frequency: str
should_expire: bool
reminder_expiration_date_time: Optional[datetime.datetime]
next_reminder_date_time: datetime.datetime
reminder_title_reminder_id: str
when i call the save method on the model object i receive the below response:
{
"ConsumedCapacity": {
"CapacityUnits": 2.0,
"TableName": "Reminders"
}
}
Now my question is the save method is directly being called by a lambda function which is in turn called by an API Gateway POST endpoint so ideally the response should be a 201 created and instead of returning the consumed capacity and table name , would be great if it returns the item inserted in the database. Below is my route code :
def create_a_new_reminder():
"""Creates a new reminder in the database."""
request_context = app.current_request.context
request_body = json.loads(app.current_request.raw_body.decode())
request_body["reminder_frequency"] = data_structures.ReminderFrequency[request_body["reminder_frequency"]]
reminder_details = data_structures.ReminderDetailsFromRequest.parse_obj(request_body)
user_details = data_structures.UserDetails(
user_name=request_context["authorizer"]["claims"]["cognito:username"],
user_email=request_context["authorizer"]["claims"]["email"]
)
reminder_id = str(uuid.uuid1())
new_reminder = data_structures.NewReminder(
reminder_id=reminder_id,
user_id=user_details.user_name,
reminder_title=reminder_details.reminder_title,
reminder_description=reminder_details.reminder_description,
reminder_tags=reminder_details.reminder_tags,
reminder_frequency=reminder_details.reminder_frequency.value[0],
should_expire=reminder_details.should_expire,
reminder_expiration_date_time=reminder_details.reminder_expiration_date_time,
next_reminder_date_time=reminder_details.next_reminder_date_time,
reminder_title_reminder_id=f"{reminder_details.reminder_title}-{reminder_id}"
)
return DynamoBackend.create_a_new_reminder(new_reminder=new_reminder)
I am very new to REST API creation and best practices so would be great if someone would guide me here . Thanks in advance !

write an empty dict field using mongoengine

I have observed mongo documents for which document[field] returns {}, but I can't seem to create such a document. Example:
import mongoengine
mongoengine.connect('FOO', host='localhost', port=27017)
class Foo(mongoengine.Document):
some_dict = mongoengine.DictField()
message = mongoengine.StringField()
ID = '59b97ec7c5d65e0c4740b886'
foo = Foo()
foo.some_dict = {}
foo.id = ID
foo.save()
But when I query the record, some_dict is not among the fields, so the last line throws an error:
import pymongo
CON = pymongo.MongoClient('localhost',27017)
x = CON.FOO.foo.find_one()
assert str(x['_id']) == ID
assert 'some_dict' in x.keys()
One obvious workaround is to update the document after it's created, but it feels like too much of a hack. I would prefer if mongoengine made it easy to do directly:
import mongoengine
import pymongo
CON = pymongo.MongoClient('localhost',27017)
CON.Foo.foo.remove()
mongoengine.connect('FOO', host='localhost', port=27017)
class Foo(mongoengine.Document):
some_dict = mongoengine.DictField()
some_list = mongoengine.ListField()
ID = '59b97ec7c5d65e0c4740b886'
foo = Foo()
foo.id = ID
foo.save()
from bson.objectid import ObjectId
CON.FOO.foo.update_one({'_id': ObjectId(ID)},
{'$set': {'some_dict': {}}}, upsert=False)
x = CON.FOO.foo.find_one()
assert str(x['_id']) == ID
assert 'some_dict' in x.keys()

Parse date to "yyyy-MM-dd'T'00:00:00" using Groovy

I am trying to parse date format '2017-12-18T20:41:06.136Z' into "2017-12-18'T'00:00:00"
Date date = new Date();
def dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
dateformat.setTimeZone(TimeZone.getTimeZone(TimeZoneCode));
def currentDate = dateformat.format(date)
log.info "Current Date : " + currentDate
date1 = new SimpleDateFormat("yyyy-MM-dd'T'00:00:00").parse(currentDate)
log.info "Current Date : " + date1
Error displayed :
java.text.ParseException: Unparseable date: "2017-12-18T20:46:06:234Z" error at line: 16
This line gives error :
date1 = new SimpleDateFormat("yyyy-MM-dd'T'00:00:00").parse(currentDate)
Running Groovy on Java 8 gives you access to the much better Date/Time classes... You can just do:
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
String result = ZonedDateTime.parse("2017-12-18T20:41:06.136Z")
.truncatedTo(ChronoUnit.DAYS)
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
In order to avoid the mentioned error, use below statement Date.parse(..):
def dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
def dateString = "2017-12-18T20:41:06.136Z"
def date = Date.parse(dateFormat, dateString)
You should be able to achieve what you are trying to using below script.
//Change timezone if needed
def tz = 'IST'
TimeZone.setDefault(TimeZone.getTimeZone(tz))
def dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
def dateString = "2017-12-18T20:41:06.136Z"
Calendar calendar = Calendar.getInstance()
calendar.with {
time = Date.parse(dateFormat,dateString)
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
log.info calendar.time.format(dateFormat)
You can quickly try the same online demo
if you need to parse only part of date, use the following syntax:
Date.parse("yyyy-MM-dd'T'HH:mm:ss",'2017-12-18T16:05:58bla-bla')

Increment date to the next day using Groovy

Trying to add 1 day to the simple date format.
import java.text.SimpleDateFormat
Date date = new Date();
def dateformat = new SimpleDateFormat("YYYY-MM-dd")
def currentDate = dateformat.format(date)
log.info "Current Date : " + currentDate
Date date1 = (Date)dateformat.parse(currentDate);
Calendar c1 = Calendar.getInstance();
c1.setTime(date1);
log info c1.add(Calendar.Date,1);
Error occurred in line :
"log info c1.add(Calendar.Date,1);"
groovy.lang.MissingPropertyException:No such property: info for class: Script16 error at line: 10
Note : The current date should be any date in future and i want to increment by 1 day.
You can use TimeCategory to add the day as shown below:
use(groovy.time.TimeCategory) {
def tomorrow = new Date() + 1.day
log.info tomorrow.format('yyyy-MM-dd')
}
EDIT: based on OP comments
Here is another away which is to add method dynamically, say nextDay() to Date class.
//Define the date format expected
def dateFormat = 'yyyy-MM-dd'
Date.metaClass.nextDay = {
use(groovy.time.TimeCategory) {
def nDay = delegate + 1.day
nDay.format(dateFormat)
}
}
//For any date
def dateString = '2017-12-14'
def date = Date.parse(dateFormat, dateString)
log.info date.nextDay()
//For current date
def date2 = new Date()
log.info date2.nextDay()
You may quickly the same online demo
Well, the error you provide clearly tells you, that you have a syntax error. It says that there is no property info.
This is because you write
log info c1.add(Calendar.Date,1);
instead of
log.info c1.add(Calendar.Date,1);
If you would have used the correct syntax, it would complain that Calendar has no property Date.
So instead of
c1.add(Calendar.Date, 1)
you meant
c1.add(Calendar.DAY_OF_MONTH, 1)
But in Groovy you can even make it easier, using
c1 = c1.next()

wxPython: populate grid from another class using flatenotebook

I am trying to save a text file from the first page of a flatNotebook, write them to an EXTERNALLY defined sqLite database and write the values to a grid on the second page of the flatNotebook. The values are saved to the text file and written to the database successfully but I cannot get the values to populate the grid at the same time. They values show up in the grid after I close the program and restart it. I am having a hard time understanding how to call the function onAddCue(). I have tried so many things that I'm just confusing myself at this point. Please help me understand what I am doing wrong. Here is my entire code:
cue =[4,'NodeA',11,22,33,44,55,66,77,88,99]
class InitialInputs(scrolled.ScrolledPanel):
global cue
def __init__(self, parent, db):
scrolled.ScrolledPanel.__init__(self, parent, -1)
self.db = db
self.cur = self.db.con.cursor()
self.saveBtn = wx.Button(self, -1, "Save Current Values")
self.Bind(wx.EVT_BUTTON, self.onSave, self.saveBtn)
self.dirname = ""
def onSave(self, event):
global cue
dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.txt", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if dlg.ShowModal() == wx.ID_OK:
itcontains = cue
self.filename=dlg.GetFilename()
self.dirname=dlg.GetDirectory()
filehandle=open(os.path.join(self.dirname, self.filename),'w')
filehandle.write(str(itcontains))
filehandle.close()
dlg.Destroy()
row = cue[0] - 1
InsertCell ="UPDATE CUES SET 'Send'=?,'RED'=?,'GREEN'=?,'BLUE'=?,'RGB_Alpha'=?,'HUE'=?,'SAT'=?,'BRightness'=?,'HSB_Alpha'=?,'Fade'=? WHERE DTIndex=%i" %row
self.cur.execute(InsertCell, cue[1:])
self.db.con.commit()
GridPanel().grid.onAddCue() #This is the part that's not working
class Grid(gridlib.Grid):
global cue
def __init__(self, parent, db):
gridlib.Grid.__init__(self, parent, -1)
self.CreateGrid(20,10)
for row in range(20):
rowNum = row + 1
self.SetRowLabelValue(row, "cue %s" %rowNum)
self.db = db
self.cur = self.db.con.cursor()
meta = self.cur.execute("SELECT * from CUES")
labels = []
for i in meta.description:
labels.append(i[0])
labels = labels[1:]
for i in range(len(labels)):
self.SetColLabelValue(i, labels[i])
all = self.cur.execute("SELECT * from CUES ORDER by DTindex")
for row in all:
row_num = row[0]
cells = row[1:]
for i in range(len(cells)):
if cells[i] != None and cells[i] != "null":
self.SetCellValue(row_num, i, str(cells[i]))
self.Bind(gridlib.EVT_GRID_CELL_CHANGED, self.CellContentsChanged)
def CellContentsChanged(self, event):
x = event.GetCol()
y = event.GetRow()
val = self.GetCellValue(y,x)
if val == "":
val = "null"
ColLabel = self.GetColLabelValue(x)
InsertCell = "UPDATE CUES SET %s = ? WHERE DTindex = %d"%(ColLabel,y)
self.cur.execute(InsertCell, [(val),])
self.db.con.commit()
self.SetCellValue(y, x, val)
class GridPanel(wx.Panel):
def __init__(self, parent, db):
wx.Panel.__init__(self, parent, -1)
self.db = db
self.cur = self.db.con.cursor()
grid = Grid(self, db)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(grid)
self.SetSizer(sizer)
self.Fit()
def onAddCue():
global cue
row = cue[0] - 1
col=0
while col < 10:
for i in cue[1:]:
grid.SetCellValue(row, col, str(i))
col = col+1
class GetDatabase():
def __init__(self, f):
# check db file exists
try:
file = open(f)
file.close()
except IOError:
# database doesn't exist - create file & populate it
self.exists = 0
else:
# database already exists - need integrity check here
self.exists = 1
self.con = sqlite.connect(f)
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1,"Stage Lighting", size=(800,600))
panel = wx.Panel(self)
notebook = wx.Notebook(panel)
page1 = InitialInputs(notebook, db)
page2 = GridPanel(notebook, db)
notebook.AddPage(page1, "Initial Inputs")
notebook.AddPage(page2, "Grid")
sizer = wx.BoxSizer()
sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
panel.SetSizer(sizer)
self.Layout()
if __name__ == "__main__":
db = GetDatabase("data.db")
app = wx.App()
logging.basicConfig(level=logging.DEBUG)
Frame().Show()
app.MainLoop()
Apparently, the question is about python syntax errors!
onAddCue is a method belonging to the class GridPanel. The class is instantiated in the variable page2.
So, you need to call the method something like this:
page2.OnAddCue()

Resources