<file_sep>from wsgiref.simple_server import make_server
from datetime import datetime
import json

from dateutil.parser import parse
from pytz import timezone, all_timezones
from tzlocal import get_localzone

local_tz = str(get_localzone())

response_parts = [
''' 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Time app</title>
</head>
<body>
''',
'''
</body>
</html>
'''
]

def get_ok_html(tz, time):
    return '200 OK',[
        response_parts[0],
        '<h2>Time: </h2>', time.strftime('%Y-%m-%d %H:%M:%S'),
        '<h3>Zone: </h3>', tz,
        response_parts[1]
    ]

def get_bad_html():
    return '400 BAD REQUEST', [
        response_parts[0],
        '<h2>400 BAD REQUEST</h2>',
        response_parts[1]
    ]

def get_ok_json(obj):
    return '200 OK', [json.dumps(obj)]

def get_bad_json():
    return '400 BAD REQUEST', '{ "error": "BAD REQUEST" }'

def time_app(environ, start_response):
    path = environ['PATH_INFO'][1:]
    method = environ['REQUEST_METHOD']
    
    #HTML
    if not path.startswith('api') and method == 'GET':
        headers = [('Content-type', 'text/html; charset=utf-8')]
        try:
            tz = path if path != '' else local_tz
            time = datetime.now(tz= timezone(tz))

            status, body = get_ok_html(tz, time)
        except:
            status, body = get_bad_html()

    #API
    elif path.startswith('api') and method == 'POST':
        headers = [('Content-type', 'application/json; charset=utf-8')]
        try:
            length = environ['CONTENT_LENGTH']
            length = 0 if not length else int(environ['CONTENT_LENGTH'] )
            body = json.loads(environ['wsgi.input'].read(length).decode('utf-8') or '{}')

            if path == 'api/v1/time':
                tz =  body['tz'] if 'tz' in body else local_tz
                time = datetime.now(tz= timezone(tz))

                status, body = get_ok_json({'tz': tz, 'time': time.strftime('%H:%M:%S')})
            

            elif path == 'api/v1/date':
                tz = body["tz"] if "tz" in body else local_tz
                time = datetime.now(tz= timezone(tz))

                status, body = get_ok_json({'tz': tz, 'date': time.strftime('%Y-%m-%d')})

            elif path == 'api/v1/datediff':
                tz = body['start']['tz'] if 'tz' in body['start'] else local_tz
                start = timezone(tz).localize(parse(body['start']['date']))

                tz = body['end']['tz'] if 'tz' in body['end'] else local_tz
                end = timezone(tz).localize(parse(body['end']['date'])) 

                diff = end - start

                status, body = get_ok_json({'diff': str(diff)})

            else:
                status, body = get_bad_json()
            
        except:
            status, body = get_bad_json()
 
    #Any else
    else:
        headers = [('Content-type', 'text/html; charset=utf-8')]
        status, body = get_bad_html()

    start_response(status, headers)
    return [x.encode() for x in body]


if __name__ == '__main__':
    # Запуск wsgi сервера
    httpd = make_server('', 8080, time_app)
    print("Serving on port 8080...")
    httpd.serve_forever()<file_sep>import requests
import json

from tzlocal import get_localzone

url = 'http://localhost:8080/'
local_tz = str(get_localzone())

result = []

try:
    response = requests.get(url)
    assert response.status_code == 200
    assert local_tz in response.text
except:
    result.append('1')
    
try:
    response = requests.get(url + 'UTC')
    assert response.status_code == 200
    assert 'UTC' in response.text
except:
    result.append('2')

try:
    response = requests.get(url + 'Europe/Moscow')
    assert response.status_code == 200
    assert 'Europe/Moscow' in response.text
except:
    result.append('3')

try:
    response = requests.post(url + 'api')
    assert response.status_code == 400
except:
    result.append('4')

try:
    response = requests.post(url + 'api/adss')
    assert response.status_code == 400
except:
    result.append('5')

try:
    response = requests.post(url + 'api/adss')
    assert response.status_code == 400
except:
    result.append('6')

try:
    response = requests.post(url + 'api/v1')
    assert response.status_code == 400
except:
    result.append('7')

try:
    response = requests.post(url + 'api/v1/time')
    assert response.status_code == 200
except:
    result.append('8')

try:
    response = requests.post(url + 'api/v1/time')
    assert response.status_code == 200
    obj = json.loads(response.text)
    assert obj['tz'] == local_tz
except:
    result.append('9')

try:
    response = requests.post(url + 'api/v1/time', data= json.dumps({'tz': 'UTC'}))
    assert response.status_code == 200
    obj = json.loads(response.text)
    assert obj['tz'] == 'UTC'
except:
    result.append('10')
try:
    response = requests.post(url + 'api/v1/time', data= json.dumps({'tz': 'Europe/Moscow'}))
    assert response.status_code == 200
    obj = json.loads(response.text)
    assert obj['tz'] == 'Europe/Moscow'
except:
    result.append('11')

try:
    response = requests.post(url + 'api/v1/time', data= json.dumps({'tz': 'UFO'}))
    assert response.status_code == 400
except:
    result.append('12')

try:
    response = requests.post(url + 'api/v1/date', data= json.dumps({'tz': 'Europe/Moscow'}))
    assert response.status_code == 200
    obj = json.loads(response.text)
    assert obj['tz'] == 'Europe/Moscow'
except:
    result.append('13')

try:
    response = requests.post(url + 'api/v1/datediff', data= json.dumps({
        'start': { 'date': '3:30pm 2020-12-01' },
        'end': { 'date': '12.20.2020 22:21:05', 'tz': 'UTC' }
    }))
    assert response.status_code == 200
    obj = json.loads(response.text)
except:
    result.append('14')

try:
    obj = {
        'begin': { 'date': '12:30pm 2020-12-01', 'timezone': local_tz },
        'end': { 'date': '12.20.2021 22:21:05', 'tz': 'UTC' }
    }
    response = requests.post(url + 'api/v1/datediff', data= json.dumps(obj))
    assert response.status_code == 400
except:
    result.append('15')

if not result:
    print('All tests passed successfully')
else:
    for x in result:
        print('Test ' + x + ' failed')