diff --git a/Procfile b/Procfile index a096c5a6..f7300e71 100644 --- a/Procfile +++ b/Procfile @@ -1 +1,2 @@ -web: export TABPY_PORT=$PORT && export TABPY_PWD_FILE=./file.txt && tabpy-user add -u $USERNAME -p $PASSWORD -f ./file.txt && tabpy \ No newline at end of file +web: export TABPY_PORT=$PORT && export TABPY_PWD_FILE=./file.txt && tabpy-user add -u $USERNAME -p $PASSWORD -f ./file.txt && python3 external_files.py && python3 -m spacy download en_core_web_sm && tabpy + diff --git a/README.md b/README.md index 9075f07b..e9b74ceb 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/tabpy?label=PyPI%20Python%20versions) [![PyPI version](https://badge.fury.io/py/tabpy.svg)](https://pypi.python.org/pypi/tabpy/) -[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/tableau/tabpy) +[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/AmirMK/TabPy-Amir) TabPy (the Tableau Python Server) is an Analytics Extension implementation which expands Tableau's capabilities by allowing users to execute Python scripts and @@ -24,6 +24,7 @@ Consider reading TabPy documentation in the following order: * [TabPy Server Configuration Instructions](docs/server-config.md) * [Running TabPy in Virtual Environment](docs/tabpy-virtualenv.md) * [Running TabPy on Heroku](docs/deploy-to-heroku.md) +* [Running TabPy on AWS](docs/AWS-TabPy-Deployment.md) * [Authoring Python calculations in Tableau](docs/TableauConfiguration.md). * [TabPy Tools](docs/tabpy-tools.md) diff --git a/docs/AWS-TabPy-Deployment.md b/docs/AWS-TabPy-Deployment.md new file mode 100644 index 00000000..d37454fb --- /dev/null +++ b/docs/AWS-TabPy-Deployment.md @@ -0,0 +1,187 @@ +# TabPy Deployment for Tableau Cloud (AWS) +The goal of this document is to walk through all steps required to deploy TabPy on AWS with SSL connection. Although in the document we are using AWS cloud as the deployment platform, the architecture and solution is generalized to any other cloud platforms. The solution building process comprises three main steps: + +* Running TabPy on EC2 instance +* Request SSL certification with a registered domain +* Set up an application load balancer with HTTPS + +## 1. Running TabPy on EC2 Instance +AWS EC2 instance is employed as a virtual server to host python and run TabPy. The most important point in this part is we are not going to configure TabPy with HTTPS and will use load balancer with HTTPS instead: + + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/0-Overall.png) + + +Below is the walk through process to set-up an EC2 instance and install and configure TabPy. If you already have EC2 instance with TabPy up and run you may skip this section. You can find the official AWS documentation on set up Amazon EC2 [here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/get-set-up-for-amazon-ec2.html). + +## 1.1. EC2 Instance Set-up + +From your AWS console go to EC2 and lunch an instance. +In the **Lunch an instance** section, select a name and the OS for your instance (ubuntu is recommended) as well as the instance type: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/1-Create_EC2.png) + +Then you have the option to create **key pair** for your instance. That would be most useful when you want to transfer files from your local machine to your EC2 instance. So it is recommended to create the key with *ppk* format and store in the safe location: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/2-EC2_Keypair.png) +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/3-EC2_Create_Keypair.png) + +Next step is to create the **security group**. To do that click the edit bottom for security group section: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/4-Network_Setting.png) + +Pick a meaningful name and description for the security group and make sure two **inbound rules** are added: + +* *ssh* type with port 22 (Assuming the OS for your VM is Linux then we should enable ssh port othewise it should be the port consitent to the OS for example if the OS was Window the we would need to enable RDP) +* *Custom TCP* type with port 9004. + +Although TabPy by default runs on port 9004 the port number can be configured on the TabPy configuration. If you want to run TabPy with a different port number, make sure you have the corresponding inbound rule a.k.a. *Custom TCP with your desirable port number*. + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/5-TCP_Setting.png) + +In the last part you have the option to increase the storage or number of instance as well. Then go ahead a click **Lunch instance**. It may take few mins for AWS to lunch the instance. You can see the list of running instance by going to **EC2 dashboard** and **Instance (running)**: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/6-EC2_Running_1.png) + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/7-EC2_Running_2.png) + +## 1.2. Install Python and TabPy + +To install any software or package you need to connect to your EC2 instance. There are multiple ways to connect to your instance including [ssh connection](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html) (for mac) and [putty](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html) (for windows) however the most straight forward method is using the AWS UI: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/8-EC2_Connect.png) + +After connecting to the EC2 you need to run the following commands. + +`sudo apt update` + +`sudo apt install python3-pip` + +`sudo python3 –m pip install —upgrade pip` + +`sudo pip3 install tabpy` + +This commands basically install the latest version of Python and install TabPy package. If you need any other python package you can install it similarly with pip command: + +`sudo pip3 install [your-python-package]` + +## 1.3. TabPy Configuration + +The next step is to set the authentication for TabPy which is mandatory for Tableau Cloud. To do that you may create `.conf` file by stating the location of `.txt` file to store the user names and password (Please note TabPy supports basic authentication.). In the below example the file name is `pass.txt`: + +`[TabPy]` + +`TABPY_PWD_FILE = pass.txt` + +you can find more about TabPy configuration [here](https://github.com/tableau/TabPy/blob/master/docs/server-config.md) + +the `pass.txt` file needs to be created and be available on the same server as TabPy server. The next step is add user(s) for TabPy with below command: + +`tabpy-user add -u -p -f ` + + you can find more about TabPy authentication command [here](https://github.com/tableau/TabPy/blob/master/docs/server-config.md#authentication) + +At this stage, If we run TabPy from the current terminal, TabPy will be attached to the current terminal. On the other word, as soon as you close your borrower/terminal then TabPy will be shut down. Hence, we need to make sure TabPy is running as a service on background. Depend on the OS of your EC2 instance there are multiple ways to run TabPy at background. For ubuntu one of the most useful application to create sessions at background is [Tmux](https://github.com/tmux/tmux/wiki). Below is the summary of steps to run TabPy at background in ubuntu using Tmux. You can find more comprehensive reference for Tumx [here](https://tmuxcheatsheet.com/). + +* Create a new session: `tmux new-session -s [session_name]` +* Connect to the session: `tmux attach-session -t [session_name]` +* Run TabPy with the custom configuration `tabpy --config [configuration file name.conf]` +* Disconnect from the session `Crtl + b + d` + + +Now TabPy is up and running on your EC2 instance and you are able to connect **Tableau Desktop** and **Tableau Server** with host-name as the **pubic IP** address for EC2 instance and port number as 9004. However, connecting to **Tableau Cloud** still is not possible as it requires SSL connection which we are going to discuss in the next parts + +# 2. Domain Name Registeration and SSL Certification + +Tableau Cloud establishes a connection only with external servers that are configured with a trusted **3rd party certificate authority (CA)** and not with a self-signed certificate, a certificate from a private PKI, or a certificate that is not trusted by an established 3rd party CA. Hence, we need to have a valid TLS/SSL certificate from a trusted 3rd party certificate authority (CA) which required having a registered domain. +Request SSL TLS/SSL can be done with AWS certificate manager however requesting the certificate requires a registered domain. Below is the walk though process to registered a domain (if you do not have one) with AWS Route 53 and request a SSL certificate.You can find AWS official documentation about registering a new domain [here](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/domain-register.html) and about requesting a public certificate [here](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html). + +## 2.1.Register a Domain + +A registered domain to host the SSL certification is mandatory. If you already have a register domain you may skip this section otherwise you can register one with **AWS Route 53** as follow: +From AWS console go to **AWS Route 53** and select a domain name (usually there is a yearly fee associate to a domain) + +After submitting the request it may take couple of mins for AW to verify the domain registration. You will get a notification email when the domain is registered successfully. And then you will see it as part of **Registered domain** + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/9-Domain_Registory.png) + +## 2.2. Request SSL Certificate + +The next step is to request the SSL certification via **AWS certificate manager**. To do that, From AWS console go to **AWS Certificate Manager** and select request and then submit a request for a public certificate: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/10-Request%20Certificate.png) + +Then you need to pick a valid name for your domain. When you pick the name, make sure you select **Add another name to this certificate** and add *.your-domain as below: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/11-Public_Certificate.png) + +When you submit the request you may see the domain request as *pending*. Go back to **AWS certificate manager** portal and click on the *certification ID* correspond to the registered domain and select **Create records**: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/12-AWS_DNS_Record.png) + +Few mins after creating record the status of certificate will turn into **issued**: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/13-AWD_DNS_Issued.png) + +# 3. Application Load Balancer + +Application load balancer is used to route the requests to the EC2 instance on which TabPy is running. Below is the walk though process to create an application load balancer and use it as proxy for the TabPy server. You can learn more application load balancer [here](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html). + +## 3.1. Create Load Balancer + +From AWS console go to EC2 and then scroll down and find **Load Balancers** and create an **application load balancer** + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/14-Application_Load_Balancer_.png) + +Pick a name for your load balancer and make sure the VPC is the same as VPC for your EC2 instance similar for mappings (you need to pick at least two availability zones): + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/15-APB_Setting.png) + + +## 3.2.Security Group and Target Group + +The best practice is to create a new security group instead of using default ones. To do that remove any default security group and click on **create security group**. Pick a name and description for the security group and make sure the VPC is the same VPC that your TabPy EC2 instance is running on. +For the inbound and outbound rules make sure it is set to *HTTPS* type with port range 443. The outbound type can be *All traffic* + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/16-APB_Security_Group_Basic.png) + +You can learn more about AWS application load balancer security group [here](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-update-security-groups.html). + +After creating the security group go back to the load balancer page and select the created security group; + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/17-APB_Security_Group_Setting.png) + +Next set up listeners and routing by selecting HTTPS as protocol with port 443 and then select **create a target group** + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/18-APB_Security_Group_Listener.png) + +For the target group set the target type to **instance**, pick a name and make sure protocol is HTTP with port 9004 (This is port on which TabPy is running on EC2 instance): + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/19-APB_Security_Group_Config.png) + +Finally select the instance on which your are running TabPy and **include as pending below** + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/20-APB_Security_Group_Target.png) + +After creating the target group go back to your load balancer page and select the created target group (you should see it as part of drop down menu) + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/21-APB_Security_Group_HTTPS.png) + +In the last section ‘Secure listen setting’ select your registered domain as : + + +## 3.2.Route Traffic to Load Balancer + +The final step is to route the web traffic to the load balancer. +From AWS console go to **AWS Route 53** dashboard and under **DSN management** select **Hosted zones** and then select the registers domain you created. Then create a record and assign a record name (This would be the host-name for TabPy connection to Tableau Cloud) and make sure rest of the configuration is as below: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/22-APB_Security_Group_Final.png) + +After creating the record you should have it as pat of: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/23-Create_Record_1.png) + +It may take couple of mins for record to get effective and working. When the record gets effective you will be able to connect Tableau cloud/Desktop/Server to the TabPy server with secured connection via SSL. To connect to TabPy, your hostname would be the record name, port number is 443: + +![alt text](https://github.com/AmirMK/TabPy-Amir/blob/master/docs/img/AWS-Deployment/25-TOL_Connection.png) + diff --git a/docs/img/AWS-Deployment/0-Overall.png b/docs/img/AWS-Deployment/0-Overall.png new file mode 100644 index 00000000..9436a97a Binary files /dev/null and b/docs/img/AWS-Deployment/0-Overall.png differ diff --git a/docs/img/AWS-Deployment/1-Create_EC2.png b/docs/img/AWS-Deployment/1-Create_EC2.png new file mode 100644 index 00000000..6dd2c592 Binary files /dev/null and b/docs/img/AWS-Deployment/1-Create_EC2.png differ diff --git a/docs/img/AWS-Deployment/10-Request Certificate.png b/docs/img/AWS-Deployment/10-Request Certificate.png new file mode 100644 index 00000000..30157ef1 Binary files /dev/null and b/docs/img/AWS-Deployment/10-Request Certificate.png differ diff --git a/docs/img/AWS-Deployment/11-Public_Certificate.png b/docs/img/AWS-Deployment/11-Public_Certificate.png new file mode 100644 index 00000000..80c79568 Binary files /dev/null and b/docs/img/AWS-Deployment/11-Public_Certificate.png differ diff --git a/docs/img/AWS-Deployment/12-AWS_DNS_Record.png b/docs/img/AWS-Deployment/12-AWS_DNS_Record.png new file mode 100644 index 00000000..14ef38dc Binary files /dev/null and b/docs/img/AWS-Deployment/12-AWS_DNS_Record.png differ diff --git a/docs/img/AWS-Deployment/13-AWD_DNS_Issued.png b/docs/img/AWS-Deployment/13-AWD_DNS_Issued.png new file mode 100644 index 00000000..2b4489c2 Binary files /dev/null and b/docs/img/AWS-Deployment/13-AWD_DNS_Issued.png differ diff --git a/docs/img/AWS-Deployment/14-Application_Load_Balancer_.png b/docs/img/AWS-Deployment/14-Application_Load_Balancer_.png new file mode 100644 index 00000000..1cdcd00a Binary files /dev/null and b/docs/img/AWS-Deployment/14-Application_Load_Balancer_.png differ diff --git a/docs/img/AWS-Deployment/15-APB_Setting.png b/docs/img/AWS-Deployment/15-APB_Setting.png new file mode 100644 index 00000000..9eaf646b Binary files /dev/null and b/docs/img/AWS-Deployment/15-APB_Setting.png differ diff --git a/docs/img/AWS-Deployment/16-APB_Security_Group_Basic.png b/docs/img/AWS-Deployment/16-APB_Security_Group_Basic.png new file mode 100644 index 00000000..b975d3a7 Binary files /dev/null and b/docs/img/AWS-Deployment/16-APB_Security_Group_Basic.png differ diff --git a/docs/img/AWS-Deployment/17-APB_Security_Group_Setting.png b/docs/img/AWS-Deployment/17-APB_Security_Group_Setting.png new file mode 100644 index 00000000..fc3b9b34 Binary files /dev/null and b/docs/img/AWS-Deployment/17-APB_Security_Group_Setting.png differ diff --git a/docs/img/AWS-Deployment/18-APB_Security_Group_Listener.png b/docs/img/AWS-Deployment/18-APB_Security_Group_Listener.png new file mode 100644 index 00000000..0222d206 Binary files /dev/null and b/docs/img/AWS-Deployment/18-APB_Security_Group_Listener.png differ diff --git a/docs/img/AWS-Deployment/19-APB_Security_Group_Config.png b/docs/img/AWS-Deployment/19-APB_Security_Group_Config.png new file mode 100644 index 00000000..2364d1fa Binary files /dev/null and b/docs/img/AWS-Deployment/19-APB_Security_Group_Config.png differ diff --git a/docs/img/AWS-Deployment/2-EC2_Keypair.png b/docs/img/AWS-Deployment/2-EC2_Keypair.png new file mode 100644 index 00000000..9b755833 Binary files /dev/null and b/docs/img/AWS-Deployment/2-EC2_Keypair.png differ diff --git a/docs/img/AWS-Deployment/20-APB_Security_Group_Target.png b/docs/img/AWS-Deployment/20-APB_Security_Group_Target.png new file mode 100644 index 00000000..42e550cb Binary files /dev/null and b/docs/img/AWS-Deployment/20-APB_Security_Group_Target.png differ diff --git a/docs/img/AWS-Deployment/21-APB_Security_Group_HTTPS.png b/docs/img/AWS-Deployment/21-APB_Security_Group_HTTPS.png new file mode 100644 index 00000000..efef1127 Binary files /dev/null and b/docs/img/AWS-Deployment/21-APB_Security_Group_HTTPS.png differ diff --git a/docs/img/AWS-Deployment/22-APB_Security_Group_Final.png b/docs/img/AWS-Deployment/22-APB_Security_Group_Final.png new file mode 100644 index 00000000..597da2c5 Binary files /dev/null and b/docs/img/AWS-Deployment/22-APB_Security_Group_Final.png differ diff --git a/docs/img/AWS-Deployment/23-Create_Record_1.png b/docs/img/AWS-Deployment/23-Create_Record_1.png new file mode 100644 index 00000000..eedf4b2c Binary files /dev/null and b/docs/img/AWS-Deployment/23-Create_Record_1.png differ diff --git a/docs/img/AWS-Deployment/24-Create_Record_2.png b/docs/img/AWS-Deployment/24-Create_Record_2.png new file mode 100644 index 00000000..a84304b8 Binary files /dev/null and b/docs/img/AWS-Deployment/24-Create_Record_2.png differ diff --git a/docs/img/AWS-Deployment/25-TOL_Connection.png b/docs/img/AWS-Deployment/25-TOL_Connection.png new file mode 100644 index 00000000..11ebb975 Binary files /dev/null and b/docs/img/AWS-Deployment/25-TOL_Connection.png differ diff --git a/docs/img/AWS-Deployment/3-EC2_Create_Keypair.png b/docs/img/AWS-Deployment/3-EC2_Create_Keypair.png new file mode 100644 index 00000000..34ae0caf Binary files /dev/null and b/docs/img/AWS-Deployment/3-EC2_Create_Keypair.png differ diff --git a/docs/img/AWS-Deployment/4-Network_Setting.png b/docs/img/AWS-Deployment/4-Network_Setting.png new file mode 100644 index 00000000..0031b76d Binary files /dev/null and b/docs/img/AWS-Deployment/4-Network_Setting.png differ diff --git a/docs/img/AWS-Deployment/5-TCP_Setting.png b/docs/img/AWS-Deployment/5-TCP_Setting.png new file mode 100644 index 00000000..5c29d467 Binary files /dev/null and b/docs/img/AWS-Deployment/5-TCP_Setting.png differ diff --git a/docs/img/AWS-Deployment/6-EC2_Running_1.png b/docs/img/AWS-Deployment/6-EC2_Running_1.png new file mode 100644 index 00000000..a5bf97f2 Binary files /dev/null and b/docs/img/AWS-Deployment/6-EC2_Running_1.png differ diff --git a/docs/img/AWS-Deployment/7-EC2_Running_2.png b/docs/img/AWS-Deployment/7-EC2_Running_2.png new file mode 100644 index 00000000..22619280 Binary files /dev/null and b/docs/img/AWS-Deployment/7-EC2_Running_2.png differ diff --git a/docs/img/AWS-Deployment/8-EC2_Connect.png b/docs/img/AWS-Deployment/8-EC2_Connect.png new file mode 100644 index 00000000..3d5565bd Binary files /dev/null and b/docs/img/AWS-Deployment/8-EC2_Connect.png differ diff --git a/docs/img/AWS-Deployment/9-Domain_Registory.png b/docs/img/AWS-Deployment/9-Domain_Registory.png new file mode 100644 index 00000000..0c38268d Binary files /dev/null and b/docs/img/AWS-Deployment/9-Domain_Registory.png differ diff --git a/external_files.py b/external_files.py new file mode 100644 index 00000000..f06b6b0f --- /dev/null +++ b/external_files.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 25 14:59:23 2022 + +@author: ameimand +""" + +import requests +URL = 'https://raw.githubusercontent.com/arunponnusamy/object-detection-opencv/master/yolov3.txt' +response = requests.get(URL) +open('yolov3.txt', 'wb').write(response.content) + +URL = 'https://pjreddie.com/media/files/yolov3.weights' +response = requests.get(URL) +open('yolov3.weights', 'wb').write(response.content) + +URL = 'https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov3.cfg' +response = requests.get(URL) +open('yolov3.cfg', 'wb').write(response.content) \ No newline at end of file diff --git a/setup.py b/setup.py index fa8baa8c..b6d24fb4 100755 --- a/setup.py +++ b/setup.py @@ -85,11 +85,17 @@ def read(fname): "requests", "scipy", "simplejson", - "sklearn", + "scikit-learn", "textblob", "tornado", "twisted", "urllib3", + "networkx", + "community", + "opencv-python-headless", + "spacy", + "pyflightdata", + "salesforce-merlion", ], entry_points={ "console_scripts": [ diff --git a/tabpy/tabpy_server/app/app.py b/tabpy/tabpy_server/app/app.py index 4ab95161..d590864b 100644 --- a/tabpy/tabpy_server/app/app.py +++ b/tabpy/tabpy_server/app/app.py @@ -15,6 +15,7 @@ from tabpy.tabpy_server.psws.callbacks import init_model_evaluator, init_ps_server from tabpy.tabpy_server.psws.python_service import PythonService, PythonServiceHandler from tabpy.tabpy_server.handlers import ( + BaseStaticHandler, EndpointHandler, EndpointsHandler, EvaluationPlaneHandler, @@ -85,12 +86,12 @@ def run(self): init_model_evaluator(self.settings, self.tabpy_state, self.python_service) protocol = self.settings[SettingsParameters.TransferProtocol] - ssl_options = None + ssl_options = None if protocol == "https": ssl_options = { "certfile": self.settings[SettingsParameters.CertificateFile], "keyfile": self.settings[SettingsParameters.KeyFile], - } + } elif protocol != "http": msg = f"Unsupported transfer protocol {protocol}." logger.critical(msg) @@ -166,7 +167,8 @@ def try_exit(self): ), ( self.subdirectory + r"/(.*)", - tornado.web.StaticFileHandler, + #tornado.web.StaticFileHandler, + BaseStaticHandler, dict( path=self.settings[SettingsParameters.StaticPath], default_filename="index.html", diff --git a/tabpy/tabpy_server/handlers/__init__.py b/tabpy/tabpy_server/handlers/__init__.py index 89ae704c..1090ffd0 100644 --- a/tabpy/tabpy_server/handlers/__init__.py +++ b/tabpy/tabpy_server/handlers/__init__.py @@ -2,6 +2,7 @@ from tabpy.tabpy_server.handlers.management_handler import ManagementHandler from tabpy.tabpy_server.handlers.endpoint_handler import EndpointHandler +from tabpy.tabpy_server.handlers.static_handler import BaseStaticHandler from tabpy.tabpy_server.handlers.endpoints_handler import EndpointsHandler from tabpy.tabpy_server.handlers.evaluation_plane_handler import EvaluationPlaneDisabledHandler from tabpy.tabpy_server.handlers.evaluation_plane_handler import EvaluationPlaneHandler diff --git a/tabpy/tabpy_server/handlers/base_handler.py b/tabpy/tabpy_server/handlers/base_handler.py index 3d522b03..e78c98ba 100644 --- a/tabpy/tabpy_server/handlers/base_handler.py +++ b/tabpy/tabpy_server/handlers/base_handler.py @@ -119,7 +119,8 @@ class BaseHandler(tornado.web.RequestHandler): def initialize(self, app): self.tabpy_state = app.tabpy_state # set content type to application/json - self.set_header("Content-Type", "application/json") + self.set_header("Content-Type", "application/json") + self.set_header("Strict-Transport-Security", "preload; max-age=2592000") self.protocol = self.settings[SettingsParameters.TransferProtocol] self.port = self.settings[SettingsParameters.Port] self.python_service = app.python_service diff --git a/tabpy/tabpy_server/handlers/query_plane_handler.py b/tabpy/tabpy_server/handlers/query_plane_handler.py index 004af2b3..28955440 100644 --- a/tabpy/tabpy_server/handlers/query_plane_handler.py +++ b/tabpy/tabpy_server/handlers/query_plane_handler.py @@ -58,7 +58,7 @@ def _query(self, po_name, data, uid, qry): if isinstance(response, QuerySuccessful): response_json = response.to_json() md5_tag = md5(response_json.encode("utf-8")).hexdigest() - self.set_header("Etag", f'"{md5_tag}"') + self.set_header("Etag", f'"{md5_tag}"') return (QuerySuccessful, response.for_json(), gls_time) else: self.logger.log(logging.ERROR, f"Failed query, response: {response}") diff --git a/tabpy/tabpy_server/handlers/static_handler.py b/tabpy/tabpy_server/handlers/static_handler.py new file mode 100644 index 00000000..1289ec8c --- /dev/null +++ b/tabpy/tabpy_server/handlers/static_handler.py @@ -0,0 +1,16 @@ +import base64 +import binascii +import concurrent +import json +import logging +import tornado.web +import uuid + + + + +class BaseStaticHandler(tornado.web.StaticFileHandler): + def set_extra_headers(self, path): + # set content type to application/json + self.set_header("Strict-Transport-Security", "preload; max-age=2592000") + #self._headers["testheader"] = "test"