Skip to content

Commit

Permalink
issue_105 (#121)
Browse files Browse the repository at this point in the history
issue_105

#105
Problem:
datetime: datetime.datetime’s utcnow() and utcfromtimestamp() are deprecated and will be removed in a future version. Instead, use timezone-aware objects to represent datetimes in UTC: respectively, call now() and fromtimestamp() with the tz parameter set to datetime.UTC. (Contributed by Paul Ganssle in gh-103857.)
Solution:
To add new function to get actual datetime_now with timezone and remove timezone to save the datebase models unchanged (to use postgresql and sqlite).
Conclusion:
All timestamps converts to utc timezone and stores without timezone in the database

Reviewed-by: Aloento
Reviewed-by: Vladimir Hasko <[email protected]>
Reviewed-by: Ilia Bakhterev
  • Loading branch information
bakhterets authored Jun 17, 2024
1 parent 389ca59 commit 0b12d28
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 32 deletions.
6 changes: 3 additions & 3 deletions app/api/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
#
from datetime import datetime

from app import authorization
from app import cache
Expand All @@ -19,6 +18,7 @@
from app.api.schemas.components import ComponentSearchQueryArgs
from app.api.schemas.components import ComponentStatusArgsSchema
from app.api.schemas.components import IncidentSchema
from app.datetime import naive_utcnow
from app.models import Component
from app.models import Incident
from app.models import IncidentStatus
Expand Down Expand Up @@ -76,7 +76,7 @@ def create_new_incident(target_component, impact, text):
new_incident = Incident(
text=text,
impact=impact,
start_date=datetime.utcnow(),
start_date=naive_utcnow(),
components=[target_component],
system=True,
)
Expand Down Expand Up @@ -139,7 +139,7 @@ def handling_incidents(
f"moved to: '{dst_incident.text}'"
)
current_app.logger.debug(f"{src_incident.text} CLOSED")
src_incident.end_date = datetime.utcnow()
src_incident.end_date = naive_utcnow()
dst_incident.components.append(target_component)
handling_statuses(
src_incident,
Expand Down
27 changes: 27 additions & 0 deletions app/datetime/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
from datetime import datetime, timezone


def datetime_utcnow():
# type: () -> datetime
return datetime.now(timezone.utc)


def utc_from_timestamp(timestamp):
# type: (float) -> datetime
return datetime.fromtimestamp(timestamp, timezone.utc)


def naive_utcnow():
return datetime_utcnow().replace(tzinfo=None)
42 changes: 22 additions & 20 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
# under the License.
#

import datetime
from datetime import datetime
from typing import List

from app import db
from app.datetime import naive_utcnow

from dateutil.relativedelta import relativedelta

Expand All @@ -25,7 +26,6 @@
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy import Table
from sqlalchemy import func
from sqlalchemy import or_
from sqlalchemy import select
from sqlalchemy.orm import DeclarativeBase
Expand Down Expand Up @@ -108,9 +108,9 @@ def all_with_active_incidents():
PropComparator.and_(
or_(
Incident.end_date.is_(None),
Incident.end_date > datetime.datetime.now()
Incident.end_date > naive_utcnow()
),
Incident.start_date <= datetime.datetime.now(),
Incident.start_date <= naive_utcnow(),
),
),
)
Expand Down Expand Up @@ -171,8 +171,8 @@ def find_by_name_and_attributes(name, attributes):
def calculate_sla(self):
"""Calculate component availability on the month basis"""

time_now = datetime.datetime.now()
this_month_start = datetime.datetime(time_now.year, time_now.month, 1)
time_now = naive_utcnow()
this_month_start = datetime(time_now.year, time_now.month, 1)

outages = [inc for inc in self.incidents
if inc.impact == 3 and inc.end_date is not None]
Expand Down Expand Up @@ -271,10 +271,11 @@ class Incident(Base):
__tablename__ = "incident"
id = mapped_column(Integer, primary_key=True, index=True)
text: Mapped[str] = mapped_column(String())
start_date: Mapped[datetime.datetime] = mapped_column(
insert_default=func.now()
start_date: Mapped[datetime] = mapped_column(
db.DateTime,
insert_default=naive_utcnow()
)
end_date: Mapped[datetime.datetime] = mapped_column(nullable=True)
end_date: Mapped[datetime] = mapped_column(nullable=True)
impact: Mapped[int] = mapped_column(db.SmallInteger)
# upgrade: system: Mapped[bool] = mapped_column(Boolean, default=False)
system: Mapped[bool] = mapped_column(Boolean, default=False)
Expand All @@ -298,9 +299,9 @@ def get_all_active():
select(Incident).filter(
or_(
Incident.end_date.is_(None),
Incident.end_date > datetime.datetime.now()
Incident.end_date > naive_utcnow()
),
Incident.start_date <= datetime.datetime.now(),
Incident.start_date <= naive_utcnow(),
)
).all()

Expand All @@ -310,7 +311,7 @@ def get_all_closed():
return db.session.scalars(
select(Incident).filter(
Incident.end_date.is_not(None),
Incident.end_date < datetime.datetime.now()
Incident.end_date < naive_utcnow()
)
).all()

Expand All @@ -321,7 +322,7 @@ def get_history_by_months(incident_list):
incident_dict = {}
for incident in incident_list:
incident_dict.setdefault(
datetime.datetime(
datetime(
incident.end_date.year,
incident.end_date.month,
1),
Expand All @@ -338,11 +339,11 @@ def get_active_maintenance():
return db.session.scalars(
select(Incident).filter(
# already started
Incident.start_date <= datetime.datetime.now(),
Incident.start_date <= naive_utcnow(),
# not closed
or_(
Incident.end_date.is_(None),
Incident.end_date > datetime.datetime.now()
Incident.end_date > naive_utcnow()
),
Incident.impact == 0,
)
Expand All @@ -353,7 +354,7 @@ def get_planned_maintenances():
"""Return planned maintenances"""
return db.session.scalars(
select(Incident).filter(
Incident.start_date > datetime.datetime.now(),
Incident.start_date > naive_utcnow(),
Incident.impact == 0,
)
).all()
Expand All @@ -366,7 +367,7 @@ def get_active_m():
return db.session.scalars(
select(Incident).filter(
# already started
Incident.start_date <= datetime.datetime.now(),
Incident.start_date <= naive_utcnow(),
# not closed
Incident.end_date.is_(None),
Incident.impact != 0,
Expand All @@ -382,7 +383,7 @@ def get_active():
return db.session.scalars(
select(Incident).filter(
# already started
Incident.start_date <= datetime.datetime.now(),
Incident.start_date <= naive_utcnow(),
# not closed
Incident.end_date.is_(None),
Incident.impact != 0,
Expand Down Expand Up @@ -442,8 +443,9 @@ class IncidentStatus(Base):
id = mapped_column(Integer, primary_key=True, index=True)
incident_id = mapped_column(ForeignKey("incident.id"), index=True)
incident: Mapped["Incident"] = relationship(back_populates="updates")
timestamp: Mapped[datetime.datetime] = mapped_column(
db.DateTime, insert_default=func.now()
timestamp: Mapped[datetime] = mapped_column(
db.DateTime,
insert_default=naive_utcnow()
)
text: Mapped[str] = mapped_column(String())
status: Mapped[str] = mapped_column(String())
3 changes: 2 additions & 1 deletion app/tests/unit/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from app import create_app
from app import db
from app.datetime import naive_utcnow
from app.models import Base
from app.models import Component
from app.models import ComponentAttribute
Expand Down Expand Up @@ -74,7 +75,7 @@ def setUp(self):
text="inc",
components=[comp1],
impact=1,
end_date=datetime.datetime.now()
end_date=naive_utcnow()
- datetime.timedelta(days=1),
)
)
Expand Down
3 changes: 2 additions & 1 deletion app/tests/unit/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from app import create_app
from app import db
from app.datetime import naive_utcnow
from app.models import Base
from app.models import Component
from app.models import ComponentAttribute
Expand Down Expand Up @@ -118,7 +119,7 @@ def setUp(self):
i2 = Incident(
text="Incident2",
impact="1",
end_date=datetime.datetime.now() - datetime.timedelta(days=1),
end_date=naive_utcnow() - datetime.timedelta(days=1),
components=[comp1],
)
db.session.add(i2)
Expand Down
5 changes: 3 additions & 2 deletions app/tests/unit/test_rss.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from app import create_app
from app import db
from app.datetime import naive_utcnow
from app.models import Base
from app.models import Component
from app.models import ComponentAttribute
Expand Down Expand Up @@ -60,7 +61,7 @@ def setUp(self):
text="inc",
components=[comp1],
impact=1,
end_date=datetime.datetime.now()
end_date=naive_utcnow()
- datetime.timedelta(days=1),
)
)
Expand All @@ -69,7 +70,7 @@ def setUp(self):
text="inc2",
components=[comp2],
impact=2,
end_date=datetime.datetime.now()
end_date=naive_utcnow()
- datetime.timedelta(days=2),
)
)
Expand Down
3 changes: 2 additions & 1 deletion app/tests/unit/test_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

from app import create_app
from app import db
from app.datetime import naive_utcnow
from app.models import Base
from app.models import Component
from app.models import ComponentAttribute
Expand Down Expand Up @@ -62,7 +63,7 @@ def setUp(self):
text="inc",
components=[comp1],
impact=1,
end_date=datetime.datetime.now() - datetime.timedelta(days=1),
end_date=naive_utcnow() - datetime.timedelta(days=1),
)
db.session.add(inc1)
db.session.commit()
Expand Down
8 changes: 4 additions & 4 deletions app/web/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
#
from datetime import datetime

from app import authorization
from app import cache
from app import oauth
from app.datetime import naive_utcnow
from app.models import Component
from app.models import ComponentAttribute
from app.models import Incident
Expand Down Expand Up @@ -153,7 +153,7 @@ def new_incident(current_user):
inc.components.remove(comp)
else:
messages_to.append("Incident closed by system")
inc.end_date = datetime.now()
inc.end_date = naive_utcnow()
if messages_to:
update_incident(inc, ', '.join(messages_to))
if messages_from:
Expand Down Expand Up @@ -202,7 +202,7 @@ def incident(incident_id):
if new_status in ["completed", "resolved"]:
# Incident is completed
new_impact = incident.impact
incident.end_date = datetime.now()
incident.end_date = naive_utcnow()
current_app.logger.debug(
f"{incident} closed by {get_user_string(session['user'])}"
)
Expand Down Expand Up @@ -289,7 +289,7 @@ def history():
timeout=300,
)
def sla():
time_now = datetime.now()
time_now = naive_utcnow()
months = [time_now + relativedelta(months=-mon) for mon in range(6)]

return render_template(
Expand Down

0 comments on commit 0b12d28

Please sign in to comment.