Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Commit

Permalink
global: use UTC dates and ISO 8601 Z format
Browse files Browse the repository at this point in the history
* Stores UTC dates in the dates and validates that follow ISO 8601 Z
  format. (addresses #6)

Signed-off-by: Jose Benito Gonzalez Lopez <jose.benito.gonzalez@cern.ch>
  • Loading branch information
jbenito3 committed Aug 26, 2015
1 parent 2ef2f98 commit a388979
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 16 deletions.
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ FROM python:3.4
# from the docker build cache:
RUN pip install flask \
flask-sqlalchemy \
isodate \
jsonschema \
psycopg2 \
pytest \
Expand All @@ -33,6 +34,7 @@ RUN pip install flask \
pytest-isort \
pytest-pep8 \
pytest-pep257 \
pytz \
sphinx

# Add sources to `code` and work there:
Expand Down
30 changes: 30 additions & 0 deletions claimstore/core/datetime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
#
# This file is part of ClaimStore.
# Copyright (C) 2015 CERN.
#
# ClaimStore is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# ClaimStore is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ClaimStore; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
# USA.

"""DateTime related tools."""

from datetime import datetime

import pytz


def now_utc():
"""Return UTC datetime with tzinfo."""
return pytz.utc.localize(datetime.utcnow())
21 changes: 21 additions & 0 deletions claimstore/core/db/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
#
# This file is part of ClaimStore.
# Copyright (C) 2015 CERN.
#
# ClaimStore is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# ClaimStore is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ClaimStore; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
# USA.

"""Database related modules."""
41 changes: 41 additions & 0 deletions claimstore/core/db/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
#
# This file is part of ClaimStore.
# Copyright (C) 2015 CERN.
#
# ClaimStore is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# ClaimStore is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ClaimStore; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
# USA.

"""Custom database types."""

import pytz
from sqlalchemy import types


class UTCDateTime(types.TypeDecorator):

"""Custom UTC DateTime type."""

impl = types.DateTime

def process_bind_param(self, value, engine):
"""Process binding."""
if value is not None:
return value.astimezone(pytz.utc).replace(tzinfo=None)

def process_result_value(self, value, engine):
"""Process result."""
if value is not None:
return value.replace(tzinfo=pytz.utc)
11 changes: 6 additions & 5 deletions claimstore/modules/claims/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
from sqlalchemy.dialects.postgresql import JSONB, UUID

from claimstore.app import db
from claimstore.core.datetime import now_utc
from claimstore.core.db.types import UTCDateTime


class Claim(db.Model):
Expand All @@ -42,9 +44,8 @@ class Claim(db.Model):
default=lambda: str(uuid4())
)
created = db.Column(
db.DateTime,
nullable=False,
default=db.func.current_timestamp()
UTCDateTime,
nullable=False
)
claimant_id = db.Column(
db.Integer,
Expand Down Expand Up @@ -103,8 +104,8 @@ class Claimant(db.Model):
default=lambda: str(uuid4()),
)
joined = db.Column(
db.DateTime,
default=db.func.current_timestamp(),
UTCDateTime,
default=now_utc(),
)
name = db.Column(
db.String,
Expand Down
13 changes: 12 additions & 1 deletion claimstore/modules/claims/restful.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

"""Restful resources for the claims module."""

import isodate
from flask import Blueprint, jsonify, request

from claimstore.app import db
Expand Down Expand Up @@ -94,6 +95,15 @@ def submit_claim():
except Exception as e:
raise InvalidUsage('JSON data is not valid', details=str(e))

# Check if claim.datetime is ISO 8601
try:
created_dt = isodate.parse_datetime(json_data['claim']['datetime'])
except isodate.ISO8601Error as e:
raise InvalidUsage(
'Claim datetime does not follow ISO 8601 Z',
details=str(e)
)

claimant = Claimant.query.filter_by(name=json_data['claimant']).first()
if not claimant:
return jsonify({'status': 'error',
Expand Down Expand Up @@ -129,6 +139,7 @@ def submit_claim():

arguments = json_data['claim'].get('arguments', {})
new_claim = Claim(
created=created_dt,
claimant_id=claimant.uid,
subject_type_id=subject_type.uid,
subject_value=json_data['subject']['value'],
Expand All @@ -151,7 +162,7 @@ def get_claim():
"""GET service that returns the stored claims."""
return jsonify(
json_list=[
{'created': c.created,
{'created': c.created.isoformat(),
'claim_details': c.claim_details} for c in Claim.query.all()
]
)
2 changes: 1 addition & 1 deletion claimstore/static/json/examples/claim.cds.1.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"claim": {
"predicate": "is_same_as",
"datetime": "2015-05-25 11:00:00 UTC",
"datetime": "2015-05-25T11:00:00Z",
"certainty": 100,
"arguments": {
"human": "False",
Expand Down
2 changes: 1 addition & 1 deletion claimstore/static/json/examples/claim.inspire.1.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"claim": {
"predicate": "is_same_as",
"datetime": "2015-05-25 11:00:00 UTC",
"datetime": "2015-05-25T11:00:00Z",
"certainty": 80,
"arguments": {
"human": "True",
Expand Down
3 changes: 2 additions & 1 deletion claimstore/static/json/schemas/claims/claim.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
},
"datetime": {
"description": "#TODO: which date time is this?",
"type": "string"
"type": "string",
"format": "date-time"
},
"certainty": {
"description": "certainty of the claim",
Expand Down
12 changes: 6 additions & 6 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ bibcode ``2005astro.ph..1001H``::
},
"claim": {
"predicate": "is_same_as",
"datetime": "2015-05-26 11:00:00 UTC",
"datetime": "2015-05-26T11:00:00Z",
"certainty": 1,
},
"object": {
Expand All @@ -173,7 +173,7 @@ by a trusted program::
},
"claim": {
"predicate": "is_same_as",
"datetime": "2015-05-26 11:00:00 UTC",
"datetime": "2015-05-26T11:00:00Z",
"certainty": 0.9,
"arguments": {
"human": 0,
Expand All @@ -199,7 +199,7 @@ persistent CDS record ID 2001192::
},
"claim": {
"predicate": "is_same_as",
"datetime": "2015-05-26 11:00:00 UTC",
"datetime": "2015-05-26T11:00:00Z",
"certainty": 1,
"arguments": {
"human": 0,
Expand All @@ -226,7 +226,7 @@ an apprentice cataloguer::
},
"claim": {
"predicate": "is_same_as",
"datetime": "2015-05-26 11:00:00 UTC",
"datetime": "2015-05-26T11:00:00Z",
"certainty": 0.8,
"arguments": {
"human": 1,
Expand Down Expand Up @@ -265,7 +265,7 @@ in chronological order, for example::
},
"claim": {
"predicate": "is_same_as",
"datetime": "2015-05-26 11:00:00 UTC",
"datetime": "2015-05-26T11:00:00Z",
"certainty": 0.8,
"arguments": {
"human": 1,
Expand All @@ -286,7 +286,7 @@ in chronological order, for example::
},
"claim": {
"predicate": "is_same_as",
"datetime": "2015-05-26 11:00:00 UTC",
"datetime": "2015-05-26T11:00:00Z",
"certainty": 1.0,
"arguments": {
"human": 1,
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ def run_tests(self):
install_requires=[
'flask',
'flask-sqlalchemy',
'psycopg2',
'isodate',
'jsonschema',
'psycopg2',
'pytz',
],
extras_require={
'development': ['Flask-DebugToolbar'],
Expand Down

0 comments on commit a388979

Please sign in to comment.