diff --git a/.github/workflows/main_congressdataviewer.yml b/.github/workflows/main_congressdataviewer.yml new file mode 100644 index 000000000..5f8aed0d7 --- /dev/null +++ b/.github/workflows/main_congressdataviewer.yml @@ -0,0 +1,78 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions +# More info on Python, GitHub Actions, and Azure App Service: https://aka.ms/python-webapps-actions + +name: Build and deploy Python app to Azure Web App - CongressDataviewer + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python version + uses: actions/setup-python@v1 + with: + python-version: '3.12' + + - name: Create and start virtual environment + run: | + python -m venv venv + source venv/bin/activate + + - name: Install dependencies + run: pip install -r requirements.txt + + # Optional: Add step to run tests here (PyTest, Django test suites, etc.) + + - name: Zip artifact for deployment + run: zip release.zip ./* -r + + - name: Upload artifact for deployment jobs + uses: actions/upload-artifact@v3 + with: + name: python-app + path: | + release.zip + !venv/ + + deploy: + runs-on: ubuntu-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + permissions: + id-token: write #This is required for requesting the JWT + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v3 + with: + name: python-app + + - name: Unzip artifact for deployment + run: unzip release.zip + + + - name: Login to Azure + uses: azure/login@v1 + with: + client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_2BC5206096AF48FBBEFF7D3A0CFA0347 }} + tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_21569C5D58C74B588A8CEC30D8065834 }} + subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_7BDFB2DEF9364786B7762F0B824903D2 }} + + - name: 'Deploy to Azure Web App' + uses: azure/webapps-deploy@v2 + id: deploy-to-webapp + with: + app-name: 'CongressDataviewer' + slot-name: 'Production' + \ No newline at end of file diff --git a/app.py b/app.py index 3d1808cf6..793333068 100644 --- a/app.py +++ b/app.py @@ -1,32 +1,57 @@ +from flask import Flask, render_template, request, jsonify +import requests +from dotenv import load_dotenv import os -from flask import (Flask, redirect, render_template, request, - send_from_directory, url_for) +# Load environment variables from .env file +load_dotenv() app = Flask(__name__) +# Retrieve the values from environment variables +TOKEN_ENDPOINT = os.getenv('TOKEN_ENDPOINT') +DATA_ENDPOINT = os.getenv('DATA_ENDPOINT') +CLIENT_ID = os.getenv('CLIENT_ID') +USERNAME = os.getenv('USER') +PASSWORD = os.getenv('PASSWORD') @app.route('/') def index(): - print('Request for index page received') - return render_template('index.html') - -@app.route('/favicon.ico') -def favicon(): - return send_from_directory(os.path.join(app.root_path, 'static'), - 'favicon.ico', mimetype='image/vnd.microsoft.icon') - -@app.route('/hello', methods=['POST']) -def hello(): - name = request.form.get('name') - - if name: - print('Request for hello page received with name=%s' % name) - return render_template('hello.html', name = name) - else: - print('Request for hello page received with no name or blank name -- redirecting') - return redirect(url_for('index')) - + return render_template('form.html') + +@app.route('/data//', methods=['GET']) +def data(event_code, participant_id): + # Get the access token + token_response = requests.post( + TOKEN_ENDPOINT, + headers={ + 'Content-Type': 'application/x-www-form-urlencoded', + }, + data={ + 'grant_type': 'password', + 'username': USERNAME, + 'password': PASSWORD, + 'client_id': CLIENT_ID + } + ) + token = token_response.json().get('access_token') + + # Use the token to get the data + data_response = requests.get( + f"{DATA_ENDPOINT}?eventCode={event_code}&filter={{\"participantIdOrUuid\": \"{participant_id}\"}}", + headers={ + 'Authorization': f'Bearer {token}', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Accept': 'application/json' + } + ) + + + data = data_response.json() + print("API Response:", data) + + # Render the data in the HTML table + return render_template('table.html', data=data) if __name__ == '__main__': - app.run() + app.run(debug=True) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index c785af01f..1630b1ee2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,21 @@ +certifi==2024.2.2 +charset-normalizer==3.3.2 +click==8.1.7 +colorama==0.4.6 Flask==2.2.2 -gunicorn +gunicorn==21.2.0 +idna==3.7 +itsdangerous==2.1.2 +Jinja2==3.1.3 +MarkupSafe==2.1.5 +numpy==1.26.4 +packaging==24.0 +pandas==2.2.2 +python-dateutil==2.9.0.post0 +python-dotenv==1.0.1 +pytz==2024.1 +requests==2.31.0 +six==1.16.0 +tzdata==2024.1 +urllib3==2.2.1 Werkzeug==2.2.2 diff --git a/templates/form.html b/templates/form.html new file mode 100644 index 000000000..41a9caba3 --- /dev/null +++ b/templates/form.html @@ -0,0 +1,14 @@ + + + + + Enter Details + + +
+ Event Code:
+ Participant ID:
+ +
+ + diff --git a/templates/table.html b/templates/table.html new file mode 100644 index 000000000..0d80bc36c --- /dev/null +++ b/templates/table.html @@ -0,0 +1,44 @@ + + + + + + + Activity Table + + + +
+

Würth Congress - Activity Overview

+ + + + + + + + + + + + {% for participant in data['data']['records'] %} + {% for activity in participant['activities'] %} + {% if activity.wc24_act_category.value == 'Transfer' or activity.wc24_act_category.value == 'Meals' %} + + + + + + + + {% endif %} + {% endfor %} + {% endfor %} + +
ActivityDescriptionStartEndLocation
{{ activity.activityName }}{{ activity.description }}{{ activity.activityStartDateTime }}{{ activity.activityEndDateTime }}{{ activity.wc24_act_location_text.value }}
+
+ + + + + \ No newline at end of file