-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
137 lines (111 loc) · 3.35 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import datetime
import json
import re
from enum import Enum
from functools import wraps
from random import randint
from typing import List
from typing import Optional
from flask import Flask
from flask import request, Response
from pydantic import BaseModel, validator
from pydantic import ValidationError, constr
try:
from flask_restful import original_flask_make_response as make_response
except ImportError:
pass
app = Flask(__name__)
app.config['TRAP_HTTP_EXCEPTIONS'] = True
class Numeric(str):
pattern = r'^\d+(\.\d*)?$'
@classmethod
def validate(cls, v):
if not isinstance(v, str):
raise ValueError(f'str expected, got{type(v)}')
if not re.match(pattern=cls.pattern, string=v):
raise ValueError(f'Wrong value {v} for pattern {cls.pattern}')
@classmethod
def __get_validators__(cls):
yield cls.validate
def require_api_token(func):
@wraps(func)
def check_token(*args, **kwargs):
if not request.headers.get('Authorization'):
return Response(json.dumps({
"code": "unauthorized",
"message": "Auth Error",
}), status=401, mimetype='application/json')
return func(*args, **kwargs)
return check_token
class CartItem(BaseModel):
id: str
quantity: Numeric
full_price: Numeric
title: Optional[str]
stack_price: Optional[Numeric]
stack_full_price: Optional[Numeric]
class Cart(BaseModel):
items: List[CartItem]
cart_total_cost: Optional[Numeric]
cart_total_discount: Optional[Numeric]
class PaymentType(str, Enum):
cash = 'cash'
online = 'online'
class Point(BaseModel):
lat: float
lon: float
@validator('lat')
def lat_min_max(cls, lat):
if lat > 90 or lat < -90:
raise ValueError("minimum: -90 or maximum: 90")
return lat
@validator('lon')
def lon_min_max(cls, lon):
if lon > 180 or lon < -180:
raise ValueError("minimum: -180 or maximum: 180")
return lon
class Location(BaseModel):
position: Point
place_id: str
floor: Optional[str]
flat: Optional[str]
doorcode: Optional[str]
doorcode_extra: Optional[str]
entrance: Optional[str]
building_name: Optional[str]
doorbell_name: Optional[str]
left_at_door: Optional[bool]
meet_outside: Optional[bool]
no_door_call: Optional[bool]
postal_code: Optional[str]
comment: Optional[str]
class RequestOrder(BaseModel):
user_id: str
user_phone: str
cart: Cart
payment_type: PaymentType
location: Location
created_order_id: Optional[str]
use_external_delivery: Optional[bool]
@app.route('/lavka/v1/integration-entry/v1/order/submit', methods=['POST'])
# @validate(body=RequestOrder, response_many=True)
@require_api_token
def hello_world():
try:
body = RequestOrder(**request.json)
except ValidationError as e:
return Response(json.dumps({
"code": "bad_request",
"message": str(e),
"details": {
"cart": None,
"retry_after": 5
}
}), status=400)
dat = datetime.date.today()
return json.dumps({
"order_id": f"{dat.strftime('%y%m%d')}-{randint(100000, 999999)}",
"newbie": False,
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=False)