Skip to content

Commit 971adf4

Browse files
committed
intial commit
1 parent 4ed0e25 commit 971adf4

12 files changed

+505
-0
lines changed

.gitignore

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
5+
# C extensions
6+
*.so
7+
8+
# Distribution / packaging
9+
bin/
10+
build/
11+
develop-eggs/
12+
dist/
13+
eggs/
14+
lib/
15+
lib64/
16+
parts/
17+
sdist/
18+
var/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
23+
# Installer logs
24+
pip-log.txt
25+
pip-delete-this-directory.txt
26+
27+
# Unit test / coverage reports
28+
.tox/
29+
.coverage
30+
.cache
31+
nosetests.xml
32+
coverage.xml
33+
34+
# Translations
35+
*.mo
36+
37+
# Mr Developer
38+
.mr.developer.cfg
39+
.project
40+
.pydevproject
41+
42+
# Rope
43+
.ropeproject
44+
45+
# Django stuff:
46+
*.log
47+
*.pot
48+
49+
# Sphinx documentation
50+
docs/_build/

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Fractus IT d.o.o., [fractus.io](http://fractus.io)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

api/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
__author__ = 'fractus.io'
2+
import api.items

api/items.py

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
from connexion import NoContent
2+
from flask import jsonify, abort, make_response
3+
from models import Item, ItemSchema
4+
from config import db
5+
import logging
6+
7+
def get_all():
8+
9+
items = Item.query.order_by(Item.id).all()
10+
11+
return ItemSchema(many=True).dump(items)
12+
13+
def get_by_id(item_id):
14+
15+
item = Item.query.filter(Item.id == item_id).one_or_none()
16+
17+
if item is not None:
18+
19+
item_schema = ItemSchema()
20+
data = item_schema.dump(item)
21+
return data
22+
23+
else:
24+
abort(
25+
404,
26+
"Item not found for Id: {item_id}".format(item_id=item_id),
27+
)
28+
29+
def insert(item):
30+
31+
print("insert")
32+
id = item['id']
33+
name = item['name']
34+
35+
existing_item = (
36+
Item.query.filter(Item.id == id)
37+
.filter(Item.name == name)
38+
.one_or_none()
39+
)
40+
41+
if existing_item is None:
42+
43+
schema = ItemSchema()
44+
new_item= schema.load(item, session=db.session)
45+
46+
db.session.add(new_item)
47+
db.session.commit()
48+
49+
data = schema.dump(new_item)
50+
51+
return data, 201
52+
53+
else:
54+
abort(
55+
409,
56+
"Item id:{id}, name:{name} exists already".format(
57+
id=id, name=name
58+
),
59+
)
60+
61+
def delete(item_id):
62+
63+
item = Item.query.filter(Item.id == item_id).one_or_none()
64+
65+
if item is not None:
66+
67+
db.session.delete(item)
68+
db.session.commit()
69+
return make_response(
70+
"Item {item_id} deleted".format(item_id=item_id), 200
71+
)
72+
else:
73+
abort(
74+
404,
75+
"Item not found for Id: {item_id}".format(item_id=item_id),
76+
)
77+
78+
def update(item_id, item):
79+
80+
id = item['id']
81+
name = item['name']
82+
83+
existing_item = (
84+
Item.query.filter(Item.id == id)
85+
.one_or_none()
86+
)
87+
88+
if existing_item is None:
89+
abort(
90+
404,
91+
"Item not found for Id: {item_id}".format(item_id=item_id),
92+
)
93+
else:
94+
95+
schema = ItemSchema()
96+
updated_item = schema.load(item, session=db.session)
97+
98+
updated_item.id = existing_item.id
99+
100+
db.session.merge(updated_item)
101+
db.session.commit()
102+
103+
data = schema.dump(updated_item)
104+
105+
return data, 200
106+
107+
108+

app.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from connexion.resolver import RestyResolver
2+
3+
import connexion
4+
import os
5+
6+
import config
7+
8+
app = config.connexion_app
9+
app.add_api('items.yaml', resolver = RestyResolver('api'))
10+
11+
if __name__ == '__main__':
12+
13+
app.run(port = 9090)

build_db.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import os
2+
from config import db
3+
from models import Item, ItemSchema
4+
5+
# Data to initialize database with
6+
items = [
7+
{"id": 0, "name":"first item"},
8+
{"id": 1, "name":"second item"}
9+
]
10+
11+
# Delete database file if it exists currently
12+
if os.path.exists("items.db"):
13+
os.remove("items.db")
14+
15+
# Create the database
16+
db.create_all()
17+
18+
# iterate over the item structure and populate the database
19+
for element in items:
20+
print(element['name'])
21+
item = Item(id = element['id'], name=element['name'])
22+
db.session.add(item)
23+
24+
db.session.commit()
25+
26+
# let's check does items are in database
27+
# Create the list of items from database
28+
29+
items = Item.query.order_by(Item.name).all()
30+
31+
# Serialize the data for the response
32+
item_schema = ItemSchema(many=True)
33+
data = item_schema.dump(items)
34+
35+
print(data)

config.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
import connexion
3+
from flask_sqlalchemy import SQLAlchemy
4+
from flask_marshmallow import Marshmallow
5+
from connexion.resolver import RestyResolver
6+
7+
8+
base_dir = os.path.dirname(os.path.abspath(__file__))
9+
database_file = "sqlite:///{}".format(os.path.join(base_dir, "items.db"))
10+
11+
connexion_app = connexion.App(__name__, specification_dir = 'swagger/')
12+
13+
app = connexion_app.app
14+
15+
app.config['SQLALCHEMY_ECHO'] = True
16+
app.config['SQLALCHEMY_DATABASE_URI'] = database_file
17+
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
18+
19+
20+
db = SQLAlchemy(app)
21+
22+
ma = Marshmallow(app)
23+
24+
25+
26+
27+

items.db

8 KB
Binary file not shown.

models.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from config import db, ma
2+
3+
class Item(db.Model):
4+
5+
__tablename__ = "item"
6+
id= db.Column(db.Integer, primary_key = True)
7+
name = db.Column(db.String(32))
8+
9+
10+
def __init__(self, id, name):
11+
self.id = id
12+
self.name = name
13+
14+
class ItemSchema(ma.ModelSchema):
15+
class Meta:
16+
model = Item
17+
sqla_session = db.session
18+

requirements.txt

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Flask
2+
connexion
3+
swagger-ui-bundle
4+
#pip install "connexion[swagger-ui]"
5+
sqlalchemy
6+
Flask-SQLAlchemy
7+
flask-marshmallow
8+
marshmallow-sqlalchemy
9+
marshmallow
10+
#Flask-Injector
11+
fastavro

swagger/items.yaml

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
swagger: "2.0"
2+
3+
info:
4+
title: "Items API"
5+
version: "1.0"
6+
7+
basePath: /v1.0
8+
9+
paths:
10+
/items/:
11+
get:
12+
tags: [Items]
13+
summary: 'Get all items'
14+
operationId: api.items.get_all
15+
responses:
16+
'200':
17+
description: 'Get all items'
18+
schema:
19+
type: array
20+
items:
21+
$ref: '#/definitions/Item'
22+
23+
post:
24+
tags: [Items]
25+
operationId: api.items.insert
26+
summary: Create na item
27+
parameters:
28+
- name: item
29+
in: body
30+
schema:
31+
$ref: '#/definitions/Item'
32+
responses:
33+
200:
34+
description: New item created
35+
36+
/items/{item_id}:
37+
get:
38+
tags: [Items]
39+
summary: 'Get item by ID'
40+
operationId: api.items.get_by_id
41+
parameters:
42+
- $ref: '#/parameters/item_id'
43+
responses:
44+
200:
45+
description: Return item
46+
schema:
47+
$ref: '#/definitions/Item'
48+
404:
49+
description: Item does not exist
50+
51+
put:
52+
tags: [Items]
53+
summary: 'Update and item'
54+
operationId: api.items.update
55+
parameters:
56+
- $ref: '#/parameters/item_id'
57+
- name: item
58+
in: body
59+
schema:
60+
$ref: '#/definitions/Item'
61+
responses:
62+
200:
63+
description: Item updated
64+
schema:
65+
$ref: '#/definitions/Item'
66+
404:
67+
description: Item does not exist
68+
69+
delete:
70+
tags: [Items]
71+
operationId: api.items.delete
72+
summary: Remove an item
73+
parameters:
74+
- $ref: '#/parameters/item_id'
75+
responses:
76+
204:
77+
description: Item deleted
78+
404:
79+
description: Item does not exist
80+
81+
parameters:
82+
item_id:
83+
name: item_id
84+
description: Item's Unique identifier
85+
in: path
86+
type: string
87+
required: true
88+
pattern: "^[a-zA-Z0-9-]+$"
89+
90+
definitions:
91+
Item:
92+
type: object
93+
properties:
94+
id:
95+
type: integer
96+
format: int64
97+
name: { type: string }

0 commit comments

Comments
 (0)