Skip to content

Commit

Permalink
chore: commit checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ivelin committed Aug 28, 2021
1 parent b739586 commit 8cf95da
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 66 deletions.
4 changes: 2 additions & 2 deletions src/ambianic/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ambianic.util import ServiceExit
from ambianic import logger, config, get_config_file, \
get_secrets_file, load_config
from ambianic.webapp.flaskr import FlaskServer
from ambianic.webapp.fastapi_server import FastapiServer

log = logging.getLogger(__name__)

Expand All @@ -19,7 +19,7 @@
MAIN_HEARTBEAT_LOG_INTERVAL = 5
ROOT_SERVERS = {
'pipelines': PipelineServer,
'web': FlaskServer,
'web': FastapiServer,
}

class AmbianicServer:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@
from pathlib import Path
from requests import get
import yaml
from ambianic import config, DEFAULT_DATA_DIR, __version__
from ambianic import config, __version__
from ambianic.util import ServiceExit, ThreadedJob, ManagedService
from ambianic.webapp.server import samples, config_sources
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

app = FastAPI()

def set_data_dir(data_dir: str = None) -> None:
app.data_dir = data_dir
# serve static files from the data directory
data_path = Path(data_dir).resolve()
app.mount("/api/data", StaticFiles(directory=data_path), name="static")


log = logging.getLogger(__name__)

# CORS (Cross-Origin Resource Sharing) Section
Expand Down Expand Up @@ -69,14 +77,13 @@ def initialize_premium_notification():

return {"status": "OK", "message": "AUTH0_ID SAVED"}

@app.get('/api/timeline', methods=['GET'])
@app.get('/api/timeline.json', methods=['GET'])
@app.get('/api/timeline')
@app.get('/api/timeline.json')
def get_timeline():
response_object = {'status': 'success'}
req_page = request.args.get('page', default=1, type=int)
log.debug('Requested timeline events page" %d', req_page)
nonlocal data_dir
resp = samples.get_timeline(page=req_page, data_dir=data_dir)
resp = samples.get_timeline(page=req_page, data_dir=app.data_dir)
response_object['timeline'] = resp
log.debug('Returning %d timeline events', len(resp))
# log.debug('Returning samples: %s ', response_object)
Expand Down Expand Up @@ -161,31 +168,6 @@ def ping():
response_object = 'pong'
return jsonify(response_object)

@app.get('/static/<path:path>')
def get_static_file(path):
return fastapi.send_from_directory('static', path)

@app.get('/api/data/<path:path>')
def get_data_file(path):
data_path = Path(DEFAULT_DATA_DIR).resolve()
log.info('Serving static data file from: %r', data_path / path)
return fastapi.send_from_directory(data_path, path)

@app.get('/client', defaults={'path': 'index.html'})
@app.get('/client/', defaults={'path': 'index.html'})
@app.get('/client/<path:path>')
def get_client_file(path):
if log.level <= logging.DEBUG: # development mode
hostname = fastapi.request.host.split(':')[0]
base_uri = 'http://{host}:1234/'.format(host=hostname)
return get(f'{base_uri}{path}').content
# production mode
return fastapi.send_from_directory('client/dist', path)

log.debug('Fastapi url map: %s', str(app.url_map))
log.debug('Fastapi config map: %s', str(app.config))
log.debug('Fastapi running in %s mode',
'development' if app.config['DEBUG'] else 'production')

log.debug('Fastapi app created.')

log.info('REST API deployed (as a Fastapi app).')

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import time
import pkg_resources
import uvicorn
from pathlib import Path
from requests import get
import yaml
Expand All @@ -28,23 +29,15 @@ def __init__(self, config):
data_dir = config.get('data_dir', None)
if not data_dir:
data_dir = DEFAULT_DATA_DIR
self.srv = None
uvi_ip_address = '0.0.0.0' # bind to all local IP addresses
uvi_port = 8778
self.uvi_ip_address = '0.0.0.0' # bind to all local IP addresses
self.uvi_port = 8778
log.info('starting fastapi/uvicorn web server on %s:%d', ip_address, port)
# if Ambianic is in DEBUG mode, start FASTAPI/uvicorn in dev mode
if log.level <= logging.DEBUG:
uvi_reload=True
uvi_debug=True
self.srv = uvicorn.run(
app,
host=uvi_ip_address,
port=uvi_port,
reload=uvi_reload,
debug=uvi_debug,
log_level=log.level,
workers=3)
app.data_dir = data_dir
self.uvi_reload=True
self.uvi_debug=True

app.set_data_dir(data_dir=data_dir)
self.fastapi_stopped = True
log.debug('Fastapi process created')

Expand All @@ -53,7 +46,14 @@ def start(self, **kwargs):
log.debug('Fastapi starting main loop')
self.fastapi_stopped = False
try:
self.srv.serve_forever()
uvicorn.run(
app,
host=self.uvi_ip_address,
port=self.uvi_port,
reload=self.uvi_reload,
debug=self.uvi_debug,
log_level=log.level,
workers=3)
except ServiceExit:
log.info('Service exit requested')
self.fastapi_stopped = True
Expand Down
15 changes: 8 additions & 7 deletions src/ambianic/webapp/server/config_sources.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

from werkzeug.exceptions import NotFound, BadRequest
from fastapi import HTTPException
from ambianic import config
import logging

Expand Down Expand Up @@ -28,12 +28,12 @@ def validate(source_id, source):

for prop in source_model:
if prop not in source_keys:
raise BadRequest(f"missing property {prop}")
raise HTTPException(status_code=400, detail=f"missing property {prop}")
if not isinstance(source[prop], source_model[prop]):
raise BadRequest(f"invalid type for {prop}")
raise HTTPException(status_code=400, detail=f"invalid type for {prop}")

if source["type"] not in source_types:
raise BadRequest(f"type should be one of {source_types}")
raise HTTPException(status_code=400, detail=f"type should be one of {source_types}")

return source

Expand All @@ -43,15 +43,16 @@ def get(source_id):
log.info("Get source_id=%s", source_id)

if not source_id:
raise BadRequest("source id is empy")
raise HTTPException(status_code=400, detail="source id is empy")

if not isinstance(source_id, str):
raise BadRequest("source id should be a string")
raise HTTPException(status_code=400, detail="source id should be a string")

source = config.sources[source_id]

if source is None:
raise NotFound("source not found")
raise HTTPException(status_code=404, detail="source not found")


return source

Expand Down
12 changes: 2 additions & 10 deletions tests/test_rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@
import yaml
import pytest
import pkg_resources
from ambianic.webapp.fastapi-app import app
from ambianic.webapp.fastapi_app import app
from ambianic import config, __version__
import logging
import os
from fastapi.testclient import TestClient

log = logging.getLogger(__name__)

test_client = TestClient(app)

def reset_config():
config.reload()

Expand All @@ -29,13 +27,7 @@ def teardown_module(module):

@pytest.fixture
def client():

app.config['TESTING'] = True

with test_client() as fclient:
# with app.app_context():
# flaskr.init_db()
yield fclient
test_client = TestClient(app)


def test_hello(client):
Expand Down

0 comments on commit 8cf95da

Please sign in to comment.