Skip to content

Commit 94b808d

Browse files
authored
[Flask Server] Use repo root as module root (#2217)
This is a better practice for reusing packages across apps and allows to have both web and nl Flask apps in the same testing. Repo module imports now are grouped together and much easier to navigate.
1 parent 44df40a commit 94b808d

File tree

142 files changed

+745
-692
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+745
-692
lines changed

__init__.py

Whitespace-only changes.

build/nl_server/Dockerfile

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ENV ENV=${ENV}
1919

2020
WORKDIR /workspace
2121

22+
COPY nl_app.py /workspace/nl_app.py
2223
COPY nl_server/requirements.txt /workspace/nl_server/requirements.txt
2324
# --no-cache-dir removes ~/.cache files, which can be a few GB.
2425
RUN pip3 install --no-cache-dir \
@@ -27,5 +28,5 @@ RUN pip3 install --no-cache-dir \
2728
COPY nl_server/. /workspace/nl_server/
2829

2930
# Run server
30-
WORKDIR /workspace/nl_server
31-
CMD exec gunicorn --timeout 60 --bind :6060 main:app
31+
WORKDIR /workspace
32+
CMD exec gunicorn --timeout 60 --bind :6060 nl_app:app

build/web_server/Dockerfile

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ENV ENV=${ENV}
1919

2020
WORKDIR /workspace
2121

22+
COPY web_app.py /workspace/web_app.py
2223
COPY server/requirements.txt /workspace/server/requirements.txt
2324
# --no-cache-dir removes ~/.cache files, which can be a few GB.
2425
RUN pip3 install --no-cache-dir \
@@ -37,5 +38,5 @@ COPY static/. /workspace/static/
3738
RUN npm run-script build
3839

3940
# Run server
40-
WORKDIR /workspace/server
41-
CMD exec gunicorn --timeout 60 --bind :8080 main:app
41+
WORKDIR /workspace
42+
CMD exec gunicorn --timeout 60 --bind :8080 web_app:app

nl_server/main.py nl_app.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import logging
1717

18-
from __init__ import create_app
18+
from nl_server.__init__ import create_app
1919

2020
logging.basicConfig(
2121
level=logging.INFO,

nl_server/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@
1616
import os
1717

1818
from flask import Flask
19-
import loader
20-
import routes
2119
import yaml
2220

21+
import nl_server.loader as loader
22+
import nl_server.routes as routes
23+
2324

2425
def create_app():
2526
app = Flask(__name__)

nl_server/embeddings.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
from typing import Dict, List, Union
1818

1919
from datasets import load_dataset
20-
import gcs
2120
from google.cloud import storage
2221
from sentence_transformers import SentenceTransformer
2322
from sentence_transformers.util import semantic_search
2423
import torch
2524

25+
import nl_server.gcs as gcs
26+
2627
TEMP_DIR = '/tmp/'
2728
MODEL_NAME = 'all-MiniLM-L6-v2'
2829

nl_server/loader.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
import logging
1616
import os
1717

18-
from embeddings import Embeddings
19-
from ner_place_model import NERPlaces
18+
from nl_server.embeddings import Embeddings
19+
from nl_server.ner_place_model import NERPlaces
2020

2121
nl_embeddings_cache_key = 'nl_embeddings'
2222
nl_ner_cache_key = 'nl_ner'

nl_server/pubsub.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414

1515
import json
1616

17-
import gcs
1817
from google.cloud import pubsub_v1
1918
from google.cloud import storage
20-
import loader
19+
20+
from nl_server import gcs
21+
from nl_server import loader
2122

2223
AUTOPUSH_FOLDER = 'autopush/'
2324
TOPIC_NAME = 'projects/datcom-204919/topics/nl-models-update'

nl_server/tests/embeddings_test.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717
import unittest
1818

1919
from diskcache import Cache
20-
from embeddings import Embeddings
21-
from loader import nl_cache_path
22-
from loader import nl_embeddings_cache_key
2320
from parameterized import parameterized
2421
from sklearn.metrics.pairwise import cosine_similarity
2522
import yaml
2623

24+
from nl_server.embeddings import Embeddings
25+
from nl_server.loader import nl_cache_path
26+
from nl_server.loader import nl_embeddings_cache_key
27+
2728
_root_dir = os.path.dirname(
2829
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
2930

nl_server/tests/ner_place_model_test.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
import unittest
1717

1818
from diskcache import Cache
19-
from loader import nl_cache_path
20-
from loader import nl_ner_cache_key
21-
from ner_place_model import NERPlaces
2219
from parameterized import parameterized
2320

21+
from nl_server.loader import nl_cache_path
22+
from nl_server.loader import nl_ner_cache_key
23+
from nl_server.ner_place_model import NERPlaces
24+
2425

2526
class TestNERPlaces(unittest.TestCase):
2627

run_nl_server.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ python3 -m pip install --upgrade pip
3030
echo "nl_server custom requirements installation: starting."
3131
./requirements_install.sh
3232
echo "nl_server custom requirements installation: done."
33-
34-
python3 main.py $PORT
3533
cd ..
34+
35+
python3 nl_app.py $PORT

run_server.sh

+2-4
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,5 @@ echo "Starting localhost with FLASK_ENV='$FLASK_ENV' on port='$PORT'"
8181

8282
python3 -m pip install --upgrade pip
8383
pip3 install -r server/requirements.txt -q
84-
cd server
85-
protoc -I=./config/ --python_out=./config ./config/subject_page.proto
86-
python3 main.py $PORT
87-
cd ..
84+
protoc -I=./server/config/ --python_out=./server/config ./server/config/subject_page.proto
85+
python3 web_app.py $PORT

run_test.sh

+8-12
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ function setup_python {
3232

3333
# Downloading the named-entity recognition (NER) library spacy and the large EN model
3434
# using the guidelines here: https://spacy.io/usage/models#production
35-
# Unfortunately, pip is not able to recognize this data (as a library) as part of
35+
# Unfortunately, pip is not able to recognize this data (as a library) as part of
3636
# requirements.txt and will try to download a new version every single time.
3737
# Reason for doing this here is that if the library is already installed, no need
38-
# to download > 560Mb file.
38+
# to download > 560Mb file.
3939
if python3 -c "import en_core_web_lg" &> /dev/null; then
4040
echo 'NER model (en_core_web_lg) already installed.'
4141
else
4242
echo 'Installing the NER model: en_core_web_lg'
4343
pip3 install $(spacy info en_core_web_lg --url)
44-
fi
44+
fi
4545
}
4646

4747
# Run test for client side code.
@@ -104,9 +104,7 @@ function run_npm_build () {
104104
function run_py_test {
105105
setup_python
106106
export FLASK_ENV=test
107-
cd server
108-
python3 -m pytest tests/ -s --ignore=sustainability
109-
cd ..
107+
python3 -m pytest server/tests/ -s --ignore=sustainability
110108

111109
# TODO(beets): add tests for other private dc instances
112110
# export FLASK_ENV=test-sustainability
@@ -117,9 +115,9 @@ function run_py_test {
117115
echo "nl_server custom requirements installation: starting."
118116
./requirements_install.sh
119117
echo "nl_server custom requirements installation: done."
120-
python3 -m pytest tests/ -s
121118
cd ..
122-
119+
python3 -m pytest nl_server/tests/ -s
120+
123121
echo -e "#### Checking Python style"
124122
if ! yapf --recursive --diff --style='{based_on_style: google, indent_width: 2}' -p server/ nl_server/ tools/ -e=*pb2.py; then
125123
echo "Fix Python lint errors by running ./run_test.sh -f"
@@ -137,16 +135,14 @@ function run_py_test {
137135
function run_webdriver_test {
138136
printf '\n\e[1;35m%-6s\e[m\n\n' "!!! Have you generated the prod client packages? Run './run_test.sh -b' first to do so"
139137
setup_python
140-
cd server
141-
if [ ! -d dist ]
138+
if [ ! -d server/dist ]
142139
then
143140
echo "no dist folder, please run ./run_test.sh -b to build js first."
144141
exit 1
145142
fi
146143
export FLASK_ENV=webdriver
147144
export GOOGLE_CLOUD_PROJECT=datcom-website-dev
148-
python3 -m pytest -n 10 --reruns 3 webdriver_tests/tests/
149-
cd ..
145+
python3 -m pytest -n 10 --reruns 3 server/webdriver_tests/tests/
150146
}
151147

152148
function run_all_tests {

server/__init__.py

+51-51
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import logging
1717
import os
1818
import tempfile
19-
import urllib.request
2019

2120
import firebase_admin
2221
from firebase_admin import credentials
@@ -28,16 +27,17 @@
2827
from flask_babel import Babel
2928
from google.cloud import secretmanager
3029
from google_auth_oauthlib.flow import Flow
31-
import lib.config as libconfig
32-
from lib.disaster_dashboard import get_disaster_dashboard_data
33-
import lib.i18n as i18n
34-
import lib.util as libutil
3530
from opencensus.ext.flask.flask_middleware import FlaskMiddleware
3631
from opencensus.ext.stackdriver.trace_exporter import StackdriverExporter
3732
from opencensus.trace.propagation import google_cloud_format
3833
from opencensus.trace.samplers import AlwaysOnSampler
39-
from services.discovery import configure_endpoints_from_ingress
40-
from services.discovery import get_health_check_urls
34+
35+
import server.lib.config as libconfig
36+
from server.lib.disaster_dashboard import get_disaster_dashboard_data
37+
import server.lib.i18n as i18n
38+
import server.lib.util as libutil
39+
from server.services.discovery import configure_endpoints_from_ingress
40+
from server.services.discovery import get_health_check_urls
4141

4242
propagator = google_cloud_format.GoogleCloudFormatPropagator()
4343

@@ -54,14 +54,14 @@ def createMiddleWare(app, exporter):
5454

5555
def register_routes_base_dc(app):
5656
# apply the blueprints for all apps
57-
from routes import dev
58-
from routes import disease
59-
from routes import import_wizard
60-
from routes import placelist
61-
from routes import protein
62-
from routes import redirects
63-
from routes import special_announcement
64-
from routes import topic_page
57+
from server.routes import dev
58+
from server.routes import disease
59+
from server.routes import import_wizard
60+
from server.routes import placelist
61+
from server.routes import protein
62+
from server.routes import redirects
63+
from server.routes import special_announcement
64+
from server.routes import topic_page
6565
app.register_blueprint(dev.bp)
6666
app.register_blueprint(disease.bp)
6767
app.register_blueprint(placelist.bp)
@@ -70,9 +70,9 @@ def register_routes_base_dc(app):
7070
app.register_blueprint(special_announcement.bp)
7171
app.register_blueprint(topic_page.bp)
7272

73-
from routes.api import disease as disease_api
74-
from routes.api import protein as protein_api
75-
from routes.api.import_detection import detection as detection_api
73+
from server.routes.api import disease as disease_api
74+
from server.routes.api import protein as protein_api
75+
from server.routes.api.import_detection import detection as detection_api
7676
app.register_blueprint(detection_api.bp)
7777
app.register_blueprint(disease_api.bp)
7878
app.register_blueprint(import_wizard.bp)
@@ -86,9 +86,9 @@ def register_routes_custom_dc(app):
8686

8787
def register_routes_stanford_dc(app, is_test, is_local):
8888
# Install blueprints specific to Stanford DC
89-
from routes import disasters
90-
from routes import event
91-
from routes.api import disaster_api
89+
from server.routes import disasters
90+
from server.routes import event
91+
from server.routes.api import disaster_api
9292
app.register_blueprint(disasters.bp)
9393
app.register_blueprint(disaster_api.bp)
9494
app.register_blueprint(event.bp)
@@ -104,23 +104,23 @@ def register_routes_stanford_dc(app, is_test, is_local):
104104

105105

106106
def register_routes_admin(app):
107-
from routes import user
107+
from server.routes import user
108108
app.register_blueprint(user.bp)
109-
from routes.api import user as user_api
109+
from server.routes.api import user as user_api
110110
app.register_blueprint(user_api.bp)
111111

112112

113113
def register_routes_common(app):
114114
# apply the blueprints for main app
115-
from routes import browser
116-
from routes import factcheck
117-
from routes import nl_interface
118-
from routes import nl_interface_next
119-
from routes import place
120-
from routes import ranking
121-
from routes import search
122-
from routes import static
123-
from routes import tools
115+
from server.routes import browser
116+
from server.routes import factcheck
117+
from server.routes import nl_interface
118+
from server.routes import nl_interface_next
119+
from server.routes import place
120+
from server.routes import ranking
121+
from server.routes import search
122+
from server.routes import static
123+
from server.routes import tools
124124
app.register_blueprint(browser.bp)
125125
app.register_blueprint(nl_interface.bp)
126126
app.register_blueprint(nl_interface_next.bp)
@@ -130,22 +130,22 @@ def register_routes_common(app):
130130
app.register_blueprint(static.bp)
131131
app.register_blueprint(tools.bp)
132132
# TODO: Extract more out to base_dc
133-
from routes.api import browser as browser_api
134-
from routes.api import choropleth
135-
from routes.api import csv
136-
from routes.api import facets
137-
from routes.api import landing_page
138-
from routes.api import node
139-
from routes.api import observation_dates
140-
from routes.api import observation_existence
141-
from routes.api import place as place_api
142-
from routes.api import point
143-
from routes.api import ranking as ranking_api
144-
from routes.api import series
145-
from routes.api import stats
146-
from routes.api import translator
147-
from routes.api import variable
148-
from routes.api import variable_group
133+
from server.routes.api import browser as browser_api
134+
from server.routes.api import choropleth
135+
from server.routes.api import csv
136+
from server.routes.api import facets
137+
from server.routes.api import landing_page
138+
from server.routes.api import node
139+
from server.routes.api import observation_dates
140+
from server.routes.api import observation_existence
141+
from server.routes.api import place as place_api
142+
from server.routes.api import point
143+
from server.routes.api import ranking as ranking_api
144+
from server.routes.api import series
145+
from server.routes.api import stats
146+
from server.routes.api import translator
147+
from server.routes.api import variable
148+
from server.routes.api import variable_group
149149
app.register_blueprint(browser_api.bp)
150150
app.register_blueprint(choropleth.bp)
151151
app.register_blueprint(csv.bp)
@@ -190,7 +190,7 @@ def create_app():
190190
app.config['API_ROOT'] = 'http://127.0.0.1:8081'
191191

192192
# Init extentions
193-
from cache import cache
193+
from server.cache import cache
194194

195195
# For some instance with fast updated data, we may not want to use memcache.
196196
if app.config['USE_MEMCACHE']:
@@ -286,8 +286,8 @@ def create_app():
286286
if os.environ.get('ENABLE_MODEL') == 'true':
287287
libutil.check_backend_ready([app.config['NL_ROOT'] + '/healthz'])
288288
# Some specific imports for the NL Interface.
289-
import lib.nl.training as libnl
290-
import services.nl as nl
289+
import server.lib.nl.training as libnl
290+
import server.services.nl as nl
291291

292292
# For the classification types available, check lib.training (libnl).
293293
classification_types = [

server/lib/config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def map_config_string(env):
5454
env_list[index + 1] = env[index + 1].upper()
5555
env_list[0] = env[0].upper()
5656
env_updated = "".join(env_list).replace('-', '')
57-
return 'configmodule.{}Config'.format(env_updated)
57+
return 'server.configmodule.{}Config'.format(env_updated)
5858

5959

6060
def get_config():

0 commit comments

Comments
 (0)