diff --git a/.do/app.yaml b/.do/app.yaml
deleted file mode 100644
index 2405d557..00000000
--- a/.do/app.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: sample-python
-services:
-- environment_slug: python
- github:
- branch: main
- deploy_on_push: true
- repo: digitalocean/sample-python
- name: sample-python
diff --git a/.do/deploy.template.yaml b/.do/deploy.template.yaml
deleted file mode 100644
index 49d9df1e..00000000
--- a/.do/deploy.template.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-spec:
- name: sample-python
- services:
- - environment_slug: python
- git:
- branch: main
- repo_clone_url: https://github.com/digitalocean/sample-python.git
- name: sample-python
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..aad4dc9a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,48 @@
+# Virtual environment
+venv/
+google_key.json
+.env
+# Compiled Python files
+__pycache__/
+*.pyc
+*.pyo
+*.pyd
+
+# Jupyter Notebook files
+.ipynb_checkpoints
+
+# Environment variables
+.env
+
+# Logs
+logs/
+*.log
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+
+# PyBuilder
+target/
+
+# Pyre type checker
+.pyre/
+
+# VS Code settings and cache
+.vscode/
+*.code-workspace
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyright
+.pyrightcache/
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..13566b81
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/PlanetIX-Python-service.iml b/.idea/PlanetIX-Python-service.iml
new file mode 100644
index 00000000..c956989b
--- /dev/null
+++ b/.idea/PlanetIX-Python-service.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..e7ed594f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..94a25f7f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..a6869ebb
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,27 @@
+# official Python base image
+FROM python:3.9-slim
+
+# working directory
+WORKDIR /app
+
+# Copy the requirements file into the container
+COPY requirements.txt .
+
+# Install the dependencies
+RUN pip install --no-cache-dir -r requirements.txt
+
+# Copy the rest of the application code into the container
+COPY . .
+
+# Expose the port the app will run on
+EXPOSE 8000
+
+# Set environment variables
+ENV GOOGLE_APPLICATION_CREDENTIALS /app/path/to/your-gcp-credentials.json
+ENV MYSQL_HOST your_mysql_host
+ENV MYSQL_USER your_mysql_user
+ENV MYSQL_PASSWORD your_mysql_password
+ENV MYSQL_DATABASE your_database_name
+
+# Start the application using Gunicorn
+CMD ["gunicorn", "--bind", "0.0.0.0:8000", "main:app"]
diff --git a/Procfile b/Procfile
index ac9d762f..dc46f1b6 100644
--- a/Procfile
+++ b/Procfile
@@ -1 +1 @@
-web: python server.py
+web: gunicorn main:app
\ No newline at end of file
diff --git a/README.md b/README.md
index b1baaefe..6b414a7c 100644
--- a/README.md
+++ b/README.md
@@ -1,56 +1,78 @@
-## Getting Started
+# PlanetIX PY service
-We provide a sample app using Python that you can deploy on App Platform. These steps will get this sample application running for you using App Platform.
+This project is a Python Flask application hosted on Digital Ocean App Platform that fetches data from Google BigQuery and saves it to a MySQL server every two hours.
-**Note: Following these steps may result in charges for the use of DigitalOcean services.**
+## Prerequisites
-### Requirements
+- Python 3.9 or higher
+- A Google Cloud account with a valid service account JSON key file
+- A MySQL server with the appropriate credentials
-* You need a DigitalOcean account. If you don't already have one, you can sign up at https://cloud.digitalocean.com/registrations/new.
+## Setup
-## Deploying the App
+### 1. Clone the repository
-Click this button to deploy the app to the DigitalOcean App Platform. If you are not logged in, you will be prompted to log in with your DigitalOcean account.
+Clone the project repository from GitHub to your local machine:
-[![Deploy to DigitalOcean](https://www.deploytodo.com/do-btn-blue.svg)](https://cloud.digitalocean.com/apps/new?repo=https://github.com/digitalocean/sample-python/tree/main)
+```bash
+git clone https://github.com/myusername/my-python-app.git
+```
+Create and activate a virtual environment
-Using this button disables the ability to automatically re-deploy your app when pushing to a branch or tag in your repository as you are using this repo directly.
+### 2. Navigate to the project directory and create a virtual environment:
-If you want to automatically re-deploy your app, [fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the GitHub repository to your account so that you have a copy of it stored to the cloud. Click the **Fork** button in the GitHub repository and follow the on-screen instructions.
+```
+cd my-python-app
+python -m venv venv
+```
+Activate the virtual environment:
-After forking the repo, you should now be viewing this README in your own GitHub org (e.g. `https://github.com//sample-python`). To deploy the new repo, visit https://cloud.digitalocean.com/apps and click **Create App**. Then, click **GitHub**, select the repository you created and select the `main` branch. App Platform will inspect the code, automatically detect the kind of component to create, and use the correct buildpack to create and deploy a container.
+On Unix-based systems (Linux/macOS):
-After clicking the **Deploy to DigitalOcean** button or completing the instructions above to fork the repo, follow these steps:
+```source venv/bin/activate```
-1. Configure the app such as specifying HTTP routes, environment variables or adding a database.
-1. Provide a name for your app and select which region you want to deploy your app to and click **Next**. The closest region to you should be selected by default. All App Platform apps are routed through a global CDN. So this will not affect your app performance, unless it needs to talk to external services.
-1. On the following screen, leave all the fields as they are and click **Next**.
-1. Confirm your **Plan** settings and how many containers you want to launch and click **Launch Basic/Pro App**.
-1. You should see a "Building..." progress indicator. You can click **View Logs** to see more details of the build.
-1. It can take a few minutes for the build to finish, but you can follow the progress in the **Deployments** tab.
-1. Once the build completes successfully, click the **Live App** link in the header and you should see your running application in a new tab, displaying the home page.
+On Windows:
-### Making Changes to Your App
+```venv\Scripts\activate.bat```
+### 3. Install the dependencies
+ Install the required dependencies using the requirements.txt file:
+```pip install -r requirements.txt```
-If you followed the steps to fork the repo and used your own copy when deploying the app, you can push changes to your fork and see App Platform automatically re-deploy the update to your app. During these automatic deployments, your application will never pause or stop serving request because App Platform offers zero-downtime deployments.
+### 4.Set up the environment variables
+ Create a .env file in the project root directory and populate it with the necessary environment variables:
-Here's an example code change you can make for this app:
+```
+GOOGLE_APPLICATION_CREDENTIALS=/path/to/your-gcp-credentials.json
+MYSQL_HOST=localhost
+MYSQL_USER=root
+MYSQL_PASSWORD=your_mysql_password
+MYSQL_DATABASE=your_database_name
+```
-1. Edit `server.py` and replace "Hello!" on line 12 with a different greeting
-1. Commit the change to the `main` branch. Normally it's a better practice to create a new branch for your change and then merge that branch to `main` after review, but for this demo you can commit to the `main` branch directly.
-1. Visit https://cloud.digitalocean.com/apps and navigate to your sample app.
-1. You should see a "Building..." progress indicator, just like when you first created the app.
-1. Once the build completes successfully, click the **Live App** link in the header and you should see your updated application running. You may need to force refresh the page in your browser (e.g. using **Shift+Reload**).
+## Running the project locally
+### Running the Flask application
+Run the Flask application with the following command:
-### Learn More
+```python main.py```
-You can learn more about the App Platform and how to manage and update your application at https://www.digitalocean.com/docs/app-platform/.
+The Flask application will start running, and you can access it at http://localhost:5000.
-## Deleting the App
-When you no longer need this sample application running live, you can delete it by following these steps:
-1. Visit the Apps control panel at https://cloud.digitalocean.com/apps.
-2. Navigate to the sample app.
-3. In the **Settings** tab, click **Destroy**.
+## Running the project with Docker
+Build the Docker images
+Build the Docker images for the Flask application and the script:
-**Note: If you do not delete your app, charges for using DigitalOcean services will continue to accrue.**
+
+```
+docker build -t my-python-app
+docker build -t my-python-app-script -f Dockerfile.script .
+```
+Run the Docker containers
+Run the Docker containers for the Flask application and the script:
+
+```
+docker run -p 8000:8000 --name my-python-app-instance my-python-app
+docker run --name my-python-app-script-instance my-python-app-script
+```
+
+The Flask application will be accessible at http://localhost:8000.
\ No newline at end of file
diff --git a/bigquery_to_mysql.py b/bigquery_to_mysql.py
new file mode 100644
index 00000000..4b4b6d04
--- /dev/null
+++ b/bigquery_to_mysql.py
@@ -0,0 +1,167 @@
+import mysql.connector
+from google.oauth2 import service_account
+from config import GOOGLE_APPLICATION_CREDENTIALS, MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE
+import pandas as pd
+from datetime import datetime
+import time
+
+def bigquery_to_mysql():
+ # Set up BigQuery client
+ # Create credentials using the service account key JSON file
+ credentials = service_account.Credentials.from_service_account_file(GOOGLE_APPLICATION_CREDENTIALS)
+
+ # Define your BigQuery SQL query here
+ query = "SELECT * FROM `annular-moon-361814.Quests.ALL_quests`"
+
+ # Read Google Big Query as Dataframe format
+ t1 = time.time()
+ df = pd.read_gbq(query, project_id='annular-moon-361814', credentials=credentials)
+
+ # Get Points Data from the file
+ points = pd.read_csv('quest_points/quest_points_new.csv')
+
+ # Fill null values with 0
+ df.fillna(0, inplace=True)
+
+ # Change datatype of spent_agold column to float
+ df.spent_agold = df.spent_agold.astype('float')
+
+ # Index player column
+ df.set_index('player', inplace=True)
+
+ # Creating a key
+ dt = datetime.now()
+ day = dt.weekday() + 1
+ week = dt.isocalendar().week
+
+ # Getting points foreach column foreach player
+ quest_points = {}
+ temp = []
+ old_name = ""
+ for row in range(len(points.index)):
+ if old_name != points.at[row, "name"]:
+ if old_name != "":
+ quest_points[old_name] = temp
+ temp = []
+ old_name = points.at[row, "name"]
+ temp.append((points.iat[row, 2], points.iat[row, 3]))
+ if(row == len(points.index) -1):
+ quest_points[old_name] = temp
+
+ # Function that returns player points
+ def get_points(name, player_points):
+ p = quest_points[name]
+ ret = 0
+ for values in p:
+ if player_points >= values[1]:
+ ret += values[0]
+ continue
+ return ret
+
+ # Creating a copy of dataframe data
+ result = df.copy()
+ cols = len(df.columns)
+ rows = len(df.index)
+
+ # Get points foreach row/column
+ for row in range(rows):
+ for col in range(cols):
+ p_a = df.iat[row, col]
+ if(p_a > 0):
+ result.iat[row, col] = get_points(df.columns[col ], p_a)
+
+ # Get sum of points foreach row
+ df['Points']=df.sum(axis='columns')
+
+ # Get actions for each row
+ df['Actions']=df.astype(bool).sum(axis=1)
+
+ # Set key foreach row
+ df['Key'] = str(day) + "-" + str(week)
+
+ # Order rows based on points value DESC
+ df = df.sort_values('Points', ascending=False)
+
+ # Setting the position for each row
+ df['Position'] = df['Points'].rank(method='dense', ascending=False).astype(int)
+
+ # Get current time and put on created_at column for each row
+ df['created_at'] = datetime.now()
+
+ batch_size = 20000
+
+ # Set up MySQL connection
+ mysql_conn = mysql.connector.connect(
+ host=MYSQL_HOST,
+ user=MYSQL_USER,
+ password=MYSQL_PASSWORD,
+ database=MYSQL_DATABASE
+ )
+
+ mysql_cursor = mysql_conn.cursor()
+
+ try:
+ values = [(player, float(ixt_speedup_hours), float(gold_badge), float(silver_badge), float(bronze_badge), float(genesis_drone), float(piercer_drone),float(y_ms),float(lc_ms),float(gg_ms),float(ne_ms),float(nl_ms),float(hb_ms),float(gws_ms),float(el_ms),float(night_drone),float(spent_agold),float(arcades_owned),float(meta_mod_burn),float(silver_badge_burn),float(bronze_badge_burn),float(energy_burn),float(aoc_badge_pack_burn),float(aoc_badge_burn),float(cd3_burn),float(avatar_burn),float(minted_facilities),float(genesis_unique_mints),float(genesis_unique_owned),float(month_1),float(month_3),float(month_6),float(month_12),float(lp_usd_staked),float(regular_raffle),float(premium_raffle),float(golden_raffle),float(piercer_rover),float(genesis_rover),float(night_rover),float(la_minted),float(ls_minted),float(lz_minted),float(ld_minted),float(ra_minted),float(rs_minted),float(rz_minted),float(rd_minted),float(ua_minted),float(us_minted),float(uz_minted),float(ud_minted),float(ca_minted),float(cs_minted),float(cz_minted),float(cd_minted),float(oa_minted),float(os_minted),float(oz_minted),float(od_minted),float(la_owned),float(ls_owned),float(lz_owned),float(ld_owned),float(ra_owned),float(rs_owned),float(rz_owned),float(rd_owned),float(ua_owned),float(us_owned),float(uz_owned),float(ud_owned),float(ca_owned),float(cs_owned),float(cz_owned),float(cd_owned),float(oa_owned),float(os_owned),float(oz_owned),float(od_owned),float(waste_collected),float(energy_collected),float(prospecting_orders),float(gws_orders), int(position), created_at) for player, ixt_speedup_hours, gold_badge, silver_badge, bronze_badge, genesis_drone,piercer_drone,y_ms,lc_ms,gg_ms,ne_ms,nl_ms,hb_ms,gws_ms,el_ms,night_drone,spent_agold,arcades_owned,meta_mod_burn,silver_badge_burn,bronze_badge_burn,energy_burn,aoc_badge_pack_burn,aoc_badge_burn,cd3_burn,avatar_burn,minted_facilities,genesis_unique_mints,genesis_unique_owned,month_1,month_3,month_6,month_12,lp_usd_staked,regular_raffle,premium_raffle,golden_raffle,piercer_rover,genesis_rover,night_rover,la_minted,ls_minted,lz_minted,ld_minted,ra_minted,rs_minted,rz_minted,rd_minted,ua_minted,us_minted,uz_minted,ud_minted,ca_minted,cs_minted,cz_minted,cd_minted,oa_minted,os_minted,oz_minted,od_minted,la_owned,ls_owned,lz_owned,ld_owned,ra_owned,rs_owned,rz_owned,rd_owned,ua_owned,us_owned,uz_owned,ud_owned,ca_owned,cs_owned,cz_owned,cd_owned,oa_owned,os_owned,oz_owned,od_owned,waste_collected,energy_collected,prospecting_orders,gws_orders,position, created_at in zip(df.index, df["ixt_speedup_hours"], df["gold_badge"], df["silver_badge"], df["bronze_badge"], df["genesis_drone"],df["piercer_drone"],df["y_ms"], df["lc_ms"], df["gg_ms"], df["ne_ms"],df["nl_ms"],df["hb_ms"],df["gws_ms"],df["el_ms"],df["night_drone"],df["spent_agold"],df["arcades_owned"],df["meta_mod_burn"],df["silver_badge_burn"],df["bronze_badge_burn"],df["energy_burn"],df["aoc_badge_pack_burn"],df["aoc_badge_burn"],df["cd3_burn"],df["avatar_burn"],df["minted_facilities"],df["genesis_unique_mints"],df["genesis_unique_owned"],df["month_1"],df["month_3"],df["month_6"],df["month_12"],df["lp_usd_staked"],df["regular_raffle"],df["premium_raffle"],df["golden_raffle"],df["piercer_rover"],df["genesis_rover"],df["night_rover"],df["la_minted"],df["ls_minted"],df["lz_minted"],df["ld_minted"],df["ra_minted"],df["rs_minted"],df["rz_minted"],df["rd_minted"],df["ua_minted"],df["us_minted"],df["uz_minted"],df["ud_minted"],df["ca_minted"],df["cs_minted"],df["cz_minted"],df["cd_minted"],df["oa_minted"],df["os_minted"],df["oz_minted"],df["od_minted"],df["la_owned"], df["ls_owned"],df["lz_owned"],df["ld_owned"], df["ra_owned"], df["rs_owned"], df["rz_owned"], df["rd_owned"],df["ua_owned"], df["us_owned"],df["uz_owned"],df["ud_owned"],df["ca_owned"],df["cs_owned"],df["cz_owned"], df["cd_owned"], df["oa_owned"], df["os_owned"], df["oz_owned"], df["od_owned"], df["waste_collected"],df["energy_collected"],df["prospecting_orders"], df["gws_orders"], df["Position"], df["created_at"])]
+ sql = "INSERT INTO player_points (player,ixt_speedup_hours,gold_badge,silver_badge,bronze_badge,genesis_drone,piercer_drone,y_ms,lc_ms,gg_ms,ne_ms,nl_ms,hb_ms,gws_ms,el_ms,night_drone,spent_agold,arcades_owned,meta_mod_burn,silver_badge_burn,bronze_badge_burn,energy_burn,aoc_badge_pack_burn,aoc_badge_burn,cd3_burn,avatar_burn,minted_facilities,genesis_unique_mints,genesis_unique_owned,month_1,month_3,month_6,month_12,lp_usd_staked,regular_raffle,premium_raffle,golden_raffle,piercer_rover,genesis_rover,night_rover,la_minted,ls_minted,lz_minted,ld_minted,ra_minted,rs_minted,rz_minted,rd_minted,ua_minted,us_minted,uz_minted,ud_minted,ca_minted,cs_minted,cz_minted,cd_minted,oa_minted,os_minted,oz_minted,od_minted,la_owned,ls_owned,lz_owned,ld_owned,ra_owned,rs_owned,rz_owned,rd_owned,ua_owned,us_owned,uz_owned,ud_owned,ca_owned,cs_owned,cz_owned,cd_owned,oa_owned,os_owned,oz_owned,od_owned,waste_collected,energy_collected,prospecting_orders,gws_orders,position, created_at) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE ixt_speedup_hours = VALUES(ixt_speedup_hours), gold_badge = VALUES(gold_badge), silver_badge = VALUES(silver_badge), bronze_badge = VALUES(bronze_badge), genesis_drone = VALUES(genesis_drone), piercer_drone = VALUES(piercer_drone), y_ms = VALUES(y_ms), lc_ms = VALUES(lc_ms), gg_ms = VALUES(gg_ms), ne_ms = VALUES(ne_ms), nl_ms = VALUES(nl_ms), hb_ms = VALUES(hb_ms), gws_ms = VALUES(gws_ms), el_ms = VALUES(el_ms), night_drone = VALUES(night_drone), spent_agold = VALUES(spent_agold), arcades_owned = VALUES(arcades_owned), meta_mod_burn = VALUES(meta_mod_burn), silver_badge_burn = VALUES(silver_badge_burn), energy_burn = VALUES(energy_burn), aoc_badge_pack_burn = VALUES(aoc_badge_pack_burn), aoc_badge_burn = VALUES(aoc_badge_burn), cd3_burn = VALUES(cd3_burn), avatar_burn = VALUES(avatar_burn), minted_facilities = VALUES(minted_facilities), genesis_unique_mints = VALUES(genesis_unique_mints), genesis_unique_owned = VALUES(genesis_unique_owned), month_1 = VALUES(month_1), month_3 = VALUES(month_3), month_6 = VALUES(month_6), month_12 = VALUES(month_12), lp_usd_staked = VALUES(lp_usd_staked), regular_raffle = VALUES(regular_raffle), premium_raffle = VALUES(premium_raffle), golden_raffle = VALUES(golden_raffle), piercer_rover = VALUES(piercer_rover), genesis_rover = VALUES(genesis_rover), night_rover = VALUES(night_rover), la_minted = VALUES(la_minted), ls_minted = VALUES(ls_minted), lz_minted = VALUES(lz_minted), ld_minted = VALUES(ld_minted), ra_minted = VALUES(ra_minted), rs_minted = VALUES(rs_minted), rz_minted = VALUES(rz_minted), rd_minted = VALUES(rd_minted), ua_minted = VALUES(ua_minted), us_minted = VALUES(us_minted), uz_minted = VALUES(uz_minted), ud_minted = VALUES(ud_minted), ca_minted = VALUES(ca_minted), cs_minted = VALUES(cs_minted), cz_minted = VALUES(cz_minted), cd_minted = VALUES(cd_minted), oa_minted = VALUES(oa_minted), os_minted = VALUES(os_minted), oz_minted = VALUES(oz_minted), od_minted = VALUES(od_minted), waste_collected = VALUES(waste_collected), energy_collected = VALUES(energy_collected), prospecting_orders = VALUES(prospecting_orders), gws_orders = VALUES(gws_orders), position = VALUES(position), created_at = VALUES(created_at);"
+ for i in range(0, len(values), batch_size):
+ batch = values[i:i+batch_size]
+ mysql_cursor.executemany(sql, batch)
+ mysql_conn.commit()
+
+ except mysql.connector.Error as error:
+ print("Failed to insert record into table {}".format(error))
+ mysql_conn.rollback()
+ if mysql_conn.is_connected():
+ mysql_conn.close()
+ finally:
+ if mysql_conn.is_connected():
+ mysql_conn.close()
+
+ if not mysql_conn.is_connected():
+ mysql_conn = mysql.connector.connect(
+ host=MYSQL_HOST,
+ user=MYSQL_USER,
+ password=MYSQL_PASSWORD,
+ database=MYSQL_DATABASE
+ )
+ mysql_cursor = mysql_conn.cursor()
+ try:
+ stats = [(player, float(points), int(actions), str(key), created_at) for player, points, actions, key, created_at in zip(df.index, df['Points'], df['Actions'], df['Key'], df['created_at'])]
+ sql2 = "INSERT INTO player_stats (player, points, actions, `key`, created_at) VALUES (%s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE points = VALUES(points), actions = VALUES(actions), `key` = VALUES(`key`), created_at = VALUES(created_at)"
+ for i in range(0, len(stats), batch_size):
+ batch = stats[i:i+batch_size]
+ mysql_cursor.executemany(sql2, batch)
+ mysql_conn.commit()
+ except mysql.connector.Error as error:
+ print("Failed to insert record into table {}".format(error))
+ mysql_conn.rollback()
+ if mysql_conn.is_connected():
+ mysql_conn.close()
+ finally:
+ if mysql_conn.is_connected():
+ mysql_conn.close()
+
+ else:
+ try:
+ stats = [(player, float(points), int(actions), str(key), created_at) for player, points, actions, key, created_at in zip(df.index, df['Points'], df['Actions'], df['Key'], df['created_at'])]
+ sql2 = "INSERT INTO player_stats (player, points, actions, `key`, created_at) VALUES (%s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE points = VALUES(points), actions = VALUES(actions), `key` = VALUES(`key`), created_at = VALUES(created_at)"
+ for i in range(0, len(stats), batch_size):
+ batch = stats[i:i+batch_size]
+ mysql_cursor.executemany(sql2, batch)
+ mysql_conn.commit()
+ except mysql.connector.Error as error:
+ print("Failed to insert record into table {}".format(error))
+ mysql_conn.rollback()
+ if mysql_conn.is_connected():
+ mysql_conn.close()
+ finally:
+ if mysql_conn.is_connected():
+ mysql_conn.close()
+
+ # Commit and close the MySQL connection
+ mysql_cursor.close()
+ mysql_conn.close()
+ print(f"Final time {((time.time() - t1) / 60):.2f} minutes.")
+
+if __name__ == "__main__":
+ bigquery_to_mysql()
diff --git a/config.py b/config.py
new file mode 100644
index 00000000..8e8f912f
--- /dev/null
+++ b/config.py
@@ -0,0 +1,19 @@
+from dotenv import load_dotenv
+import os
+import json
+
+# Load environment variables from the .env file
+load_dotenv()
+
+GOOGLE_APPLICATION_CREDENTIALS = os.environ.get("GOOGLE_APPLICATION_CREDENTIALS")
+MYSQL_HOST = os.environ.get("MYSQL_HOST")
+MYSQL_USER = os.environ.get("MYSQL_USER")
+MYSQL_PASSWORD = os.environ.get("MYSQL_PASSWORD")
+MYSQL_DATABASE = os.environ.get("MYSQL_DATABASE")
+
+# Save the Google Cloud credentials JSON to a temporary file
+with open("google_key.json", "w") as f:
+ f.write(GOOGLE_APPLICATION_CREDENTIALS)
+
+# Update the GOOGLE_APPLICATION_CREDENTIALS variable to point to the temporary file
+GOOGLE_APPLICATION_CREDENTIALS = "google_key.json"
diff --git a/do_app.yaml b/do_app.yaml
new file mode 100644
index 00000000..67c1bafd
--- /dev/null
+++ b/do_app.yaml
@@ -0,0 +1,17 @@
+name: my-python-app
+region: nyc
+services:
+ - environment_slug: python
+ github:
+ repo: myusername/my-python-app
+ branch: main
+ http_port: 8000
+ routes:
+ - path: /
+ envs:
+ - key: GOOGLE_APPLICATION_CREDENTIALS
+ scope: RUN_TIME
+ - key: MYSQL_HOST
+ scope: RUN_TIME
+ run_command: python bigquery_to_mysql.py
+ cron_spec: "0 */2 * * *"
\ No newline at end of file
diff --git a/main.py b/main.py
new file mode 100644
index 00000000..265fefac
--- /dev/null
+++ b/main.py
@@ -0,0 +1,13 @@
+from flask import Flask
+from bigquery_to_mysql import bigquery_to_mysql
+
+app = Flask(__name__)
+
+@app.route("/")
+def home():
+ bigquery_to_mysql()
+ return "Data has been updated!"
+ # return "Hello, world!"
+
+if __name__ == "__main__":
+ app.run(host="0.0.0.0")
diff --git a/quest_points/quest_points_new.csv b/quest_points/quest_points_new.csv
new file mode 100644
index 00000000..b4edcc5b
--- /dev/null
+++ b/quest_points/quest_points_new.csv
@@ -0,0 +1,366 @@
+Quest,name,Points,Roof,Total
+Mint Outlier Area,oa_minted,50,1,2200
+Mint Outlier Area,oa_minted,150,3,2200
+Mint Outlier Area,oa_minted,250,5,2200
+Mint Outlier Area,oa_minted,500,10,2200
+Mint Outlier Area,oa_minted,1250,25,2200
+Mint Common Area,ca_minted,60,1,2640
+Mint Common Area,ca_minted,180,3,2640
+Mint Common Area,ca_minted,300,5,2640
+Mint Common Area,ca_minted,600,10,2640
+Mint Common Area,ca_minted,1500,25,2640
+Mint Uncommon Area,ua_minted,70,1,3080
+Mint Uncommon Area,ua_minted,210,3,3080
+Mint Uncommon Area,ua_minted,350,5,3080
+Mint Uncommon Area,ua_minted,700,10,3080
+Mint Uncommon Area,ua_minted,1750,25,3080
+Mint Rare Area,ra_minted,80,1,3520
+Mint Rare Area,ra_minted,240,3,3520
+Mint Rare Area,ra_minted,400,5,3520
+Mint Rare Area,ra_minted,800,10,3520
+Mint Rare Area,ra_minted,2000,25,3520
+Mint Legendary Area,la_minted,90,1,3960
+Mint Legendary Area,la_minted,270,3,3960
+Mint Legendary Area,la_minted,450,5,3960
+Mint Legendary Area,la_minted,900,10,3960
+Mint Legendary Area,la_minted,2250,25,3960
+Mint Outlier Sector,os_minted,100,1,4400
+Mint Outlier Sector,os_minted,300,3,4400
+Mint Outlier Sector,os_minted,500,5,4400
+Mint Outlier Sector,os_minted,1000,10,4400
+Mint Outlier Sector,os_minted,2500,25,4400
+Mint Common Sector,cs_minted,110,1,4840
+Mint Common Sector,cs_minted,330,3,4840
+Mint Common Sector,cs_minted,550,5,4840
+Mint Common Sector,cs_minted,1100,10,4840
+Mint Common Sector,cs_minted,2750,25,4840
+Mint Uncommon Sector,us_minted,120,1,5280
+Mint Uncommon Sector,us_minted,360,3,5280
+Mint Uncommon Sector,us_minted,600,5,5280
+Mint Uncommon Sector,us_minted,1200,10,5280
+Mint Uncommon Sector,us_minted,3000,25,5280
+Mint Rare Sector,rs_minted,130,1,5720
+Mint Rare Sector,rs_minted,390,3,5720
+Mint Rare Sector,rs_minted,650,5,5720
+Mint Rare Sector,rs_minted,1300,10,5720
+Mint Rare Sector,rs_minted,3250,25,5720
+Mint Legendary Sector,ls_minted,140,1,6160
+Mint Legendary Sector,ls_minted,420,3,6160
+Mint Legendary Sector,ls_minted,700,5,6160
+Mint Legendary Sector,ls_minted,1400,10,6160
+Mint Legendary Sector,ls_minted,3500,25,6160
+Mint Outlier Zone,oz_minted,150,1,6600
+Mint Outlier Zone,oz_minted,450,3,6600
+Mint Outlier Zone,oz_minted,750,5,6600
+Mint Outlier Zone,oz_minted,1500,10,6600
+Mint Outlier Zone,oz_minted,3750,25,6600
+Mint Common Zone,cz_minted,160,1,7040
+Mint Common Zone,cz_minted,480,3,7040
+Mint Common Zone,cz_minted,800,5,7040
+Mint Common Zone,cz_minted,1600,10,7040
+Mint Common Zone,cz_minted,4000,25,7040
+Mint Uncommon Zone,uz_minted,170,1,7480
+Mint Uncommon Zone,uz_minted,510,3,7480
+Mint Uncommon Zone,uz_minted,850,5,7480
+Mint Uncommon Zone,uz_minted,1700,10,7480
+Mint Uncommon Zone,uz_minted,4250,25,7480
+Mint Rare Zone,rz_minted,180,1,7920
+Mint Rare Zone,rz_minted,540,3,7920
+Mint Rare Zone,rz_minted,900,5,7920
+Mint Rare Zone,rz_minted,1800,10,7920
+Mint Rare Zone,rz_minted,4500,25,7920
+Mint Legendary Zone,lz_minted,190,1,8360
+Mint Legendary Zone,lz_minted,570,3,8360
+Mint Legendary Zone,lz_minted,950,5,8360
+Mint Legendary Zone,lz_minted,1900,10,8360
+Mint Legendary Zone,lz_minted,4750,25,8360
+Mint Outlier Domain,od_minted,200,1,8800
+Mint Outlier Domain,od_minted,600,3,8800
+Mint Outlier Domain,od_minted,1000,5,8800
+Mint Outlier Domain,od_minted,2000,10,8800
+Mint Outlier Domain,od_minted,5000,25,8800
+Mint Common Domain,cd_minted,210,1,9240
+Mint Common Domain,cd_minted,630,3,9240
+Mint Common Domain,cd_minted,1050,5,9240
+Mint Common Domain,cd_minted,2100,10,9240
+Mint Common Domain,cd_minted,5250,25,9240
+Mint Uncommon Domain,ud_minted,220,1,9680
+Mint Uncommon Domain,ud_minted,660,3,9680
+Mint Uncommon Domain,ud_minted,1100,5,9680
+Mint Uncommon Domain,ud_minted,2200,10,9680
+Mint Uncommon Domain,ud_minted,5500,25,9680
+Mint Rare Domain,rd_minted,230,1,10120
+Mint Rare Domain,rd_minted,690,3,10120
+Mint Rare Domain,rd_minted,1150,5,10120
+Mint Rare Domain,rd_minted,2300,10,10120
+Mint Rare Domain,rd_minted,5750,25,10120
+Mint Legendary Domain,ld_minted,240,1,10560
+Mint Legendary Domain,ld_minted,720,3,10560
+Mint Legendary Domain,ld_minted,1200,5,10560
+Mint Legendary Domain,ld_minted,2400,10,10560
+Mint Legendary Domain,ld_minted,6000,25,10560
+Own Outlier Area,oa_owned,25,1,1100
+Own Outlier Area,oa_owned,75,3,1100
+Own Outlier Area,oa_owned,125,5,1100
+Own Outlier Area,oa_owned,250,10,1100
+Own Outlier Area,oa_owned,625,25,1100
+Own Common Area,ca_owned,30,1,1320
+Own Common Area,ca_owned,90,3,1320
+Own Common Area,ca_owned,150,5,1320
+Own Common Area,ca_owned,300,10,1320
+Own Common Area,ca_owned,750,25,1320
+Own Uncommon Area,ua_owned,35,1,1540
+Own Uncommon Area,ua_owned,105,3,1540
+Own Uncommon Area,ua_owned,175,5,1540
+Own Uncommon Area,ua_owned,350,10,1540
+Own Uncommon Area,ua_owned,875,25,1540
+Own Rare Area,ra_owned,40,1,1760
+Own Rare Area,ra_owned,120,3,1760
+Own Rare Area,ra_owned,200,5,1760
+Own Rare Area,ra_owned,400,10,1760
+Own Rare Area,ra_owned,1000,25,1760
+Own Legendary Area,la_owned,45,1,1980
+Own Legendary Area,la_owned,135,3,1980
+Own Legendary Area,la_owned,225,5,1980
+Own Legendary Area,la_owned,450,10,1980
+Own Legendary Area,la_owned,1125,25,1980
+Own Outlier Sector,os_owned,50,1,2200
+Own Outlier Sector,os_owned,150,3,2200
+Own Outlier Sector,os_owned,250,5,2200
+Own Outlier Sector,os_owned,500,10,2200
+Own Outlier Sector,os_owned,1250,25,2200
+Own Common Sector,cs_owned,55,1,2420
+Own Common Sector,cs_owned,165,3,2420
+Own Common Sector,cs_owned,275,5,2420
+Own Common Sector,cs_owned,550,10,2420
+Own Common Sector,cs_owned,1375,25,2420
+Own Uncommon Sector,us_owned,60,1,2640
+Own Uncommon Sector,us_owned,180,3,2640
+Own Uncommon Sector,us_owned,300,5,2640
+Own Uncommon Sector,us_owned,600,10,2640
+Own Uncommon Sector,us_owned,1500,25,2640
+Own Rare Sector,rs_owned,65,1,2860
+Own Rare Sector,rs_owned,195,3,2860
+Own Rare Sector,rs_owned,325,5,2860
+Own Rare Sector,rs_owned,650,10,2860
+Own Rare Sector,rs_owned,1625,25,2860
+Own Legendary Sector,ls_owned,70,1,3080
+Own Legendary Sector,ls_owned,210,3,3080
+Own Legendary Sector,ls_owned,350,5,3080
+Own Legendary Sector,ls_owned,700,10,3080
+Own Legendary Sector,ls_owned,1750,25,3080
+Own Outlier Zone,oz_owned,75,1,3300
+Own Outlier Zone,oz_owned,225,3,3300
+Own Outlier Zone,oz_owned,375,5,3300
+Own Outlier Zone,oz_owned,750,10,3300
+Own Outlier Zone,oz_owned,1875,25,3300
+Own Common Zone,cz_owned,80,1,3520
+Own Common Zone,cz_owned,240,3,3520
+Own Common Zone,cz_owned,400,5,3520
+Own Common Zone,cz_owned,800,10,3520
+Own Common Zone,cz_owned,2000,25,3520
+Own Uncommon Zone,uz_owned,85,1,3740
+Own Uncommon Zone,uz_owned,255,3,3740
+Own Uncommon Zone,uz_owned,425,5,3740
+Own Uncommon Zone,uz_owned,850,10,3740
+Own Uncommon Zone,uz_owned,2125,25,3740
+Own Rare Zone,rz_owned,90,1,3960
+Own Rare Zone,rz_owned,270,3,3960
+Own Rare Zone,rz_owned,450,5,3960
+Own Rare Zone,rz_owned,900,10,3960
+Own Rare Zone,rz_owned,2250,25,3960
+Own Legendary Zone,lz_owned,95,1,4180
+Own Legendary Zone,lz_owned,285,3,4180
+Own Legendary Zone,lz_owned,475,5,4180
+Own Legendary Zone,lz_owned,950,10,4180
+Own Legendary Zone,lz_owned,2375,25,4180
+Own Outlier Domain,od_owned,100,1,4400
+Own Outlier Domain,od_owned,300,3,4400
+Own Outlier Domain,od_owned,500,5,4400
+Own Outlier Domain,od_owned,1000,10,4400
+Own Outlier Domain,od_owned,2500,25,4400
+Own Common Domain,cd_owned,105,1,4620
+Own Common Domain,cd_owned,315,3,4620
+Own Common Domain,cd_owned,525,5,4620
+Own Common Domain,cd_owned,1050,10,4620
+Own Common Domain,cd_owned,2625,25,4620
+Own Uncommon Domain,ud_owned,110,1,4840
+Own Uncommon Domain,ud_owned,330,3,4840
+Own Uncommon Domain,ud_owned,550,5,4840
+Own Uncommon Domain,ud_owned,1100,10,4840
+Own Uncommon Domain,ud_owned,2750,25,4840
+Own Rare Domain,rd_owned,115,1,5060
+Own Rare Domain,rd_owned,345,3,5060
+Own Rare Domain,rd_owned,575,5,5060
+Own Rare Domain,rd_owned,1150,10,5060
+Own Rare Domain,rd_owned,2875,25,5060
+Own Legendary Domain,ld_owned,120,1,5280
+Own Legendary Domain,ld_owned,360,3,5280
+Own Legendary Domain,ld_owned,600,5,5280
+Own Legendary Domain,ld_owned,1200,10,5280
+Own Legendary Domain,ld_owned,3000,25,5280
+Own Piercer Drone,piercer_drone,5,1,655
+Own Piercer Drone,piercer_drone,50,10,655
+Own Piercer Drone,piercer_drone,100,50,655
+Own Piercer Drone,piercer_drone,500,500,655
+Own Genesis Drone,genesis_drone,10,1,660
+Own Genesis Drone,genesis_drone,50,5,660
+Own Genesis Drone,genesis_drone,100,25,660
+Own Genesis Drone,genesis_drone,500,100,660
+Own Night Drone,night_drone,15,1,665
+Own Night Drone,night_drone,50,3,665
+Own Night Drone,night_drone,100,10,665
+Own Night Drone,night_drone,500,50,665
+Own Piercer Rover,piercer_rover,5,1,655
+Own Piercer Rover,piercer_rover,50,50,655
+Own Piercer Rover,piercer_rover,100,100,655
+Own Piercer Rover,piercer_rover,500,500,655
+Own Genesis Rover,genesis_rover,10,1,660
+Own Genesis Rover,genesis_rover,50,10,660
+Own Genesis Rover,genesis_rover,100,50,660
+Own Genesis Rover,genesis_rover,500,100,660
+Own Night Rover,night_rover,15,1,665
+Own Night Rover,night_rover,50,5,665
+Own Night Rover,night_rover,100,25,665
+Own Night Rover,night_rover,500,50,665
+Own Bronze Badge,bronze_badge,1,1,56
+Own Bronze Badge,bronze_badge,5,5,56
+Own Bronze Badge,bronze_badge,50,50,56
+Own Silver Badge,silver_badge,5,1,305
+Own Silver Badge,silver_badge,50,5,305
+Own Silver Badge,silver_badge,250,50,305
+Own Gold Badge,gold_badge,50,1,800
+Own Gold Badge,gold_badge,250,5,800
+Own Gold Badge,gold_badge,500,10,800
+AOC Badges Burn,aoc_badge_burn,5,5,1280
+AOC Badges Burn,aoc_badge_burn,25,25,1280
+AOC Badges Burn,aoc_badge_burn,250,100,1280
+AOC Badges Burn,aoc_badge_burn,1000,500,1280
+AOC Bronze Badges Burn 3,bronze_badge_burn,10,5,3060
+AOC Bronze Badges Burn 3,bronze_badge_burn,50,25,3060
+AOC Bronze Badges Burn 3,bronze_badge_burn,500,100,3060
+AOC Bronze Badges Burn 3,bronze_badge_burn,2500,500,3060
+AOC Silver Badge Burn 2,silver_badge_burn,50,5,6300
+AOC Silver Badge Burn 2,silver_badge_burn,250,25,6300
+AOC Silver Badge Burn 2,silver_badge_burn,1000,100,6300
+AOC Silver Badge Burn 2,silver_badge_burn,5000,500,6300
+AOC Badge Pack Burn 51,aoc_badge_pack_burn,10,5,560
+AOC Badge Pack Burn 51,aoc_badge_pack_burn,50,25,560
+AOC Badge Pack Burn 51,aoc_badge_pack_burn,500,100,560
+Cargo Drop 3 Burn GG15,cd3_burn,50,5,1300
+Cargo Drop 3 Burn GG15,cd3_burn,250,25,1300
+Cargo Drop 3 Burn GG15,cd3_burn,1000,100,1300
+Avatars Burned,avatar_burn,100,1,19600
+Avatars Burned,avatar_burn,500,5,19600
+Avatars Burned,avatar_burn,1000,10,19600
+Avatars Burned,avatar_burn,3000,50,19600
+Avatars Burned,avatar_burn,5000,100,19600
+Avatars Burned,avatar_burn,10000,500,19600
+Own Y_ MetaShares 6,y_ms,10,1,6110
+Own Y_ MetaShares 6,y_ms,100,10,6110
+Own Y_ MetaShares 6,y_ms,1000,100,6110
+Own Y_ MetaShares 6,y_ms,5000,500,6110
+Own GWS MetaShares 30,gws_ms,10,1,6110
+Own GWS MetaShares 30,gws_ms,100,10,6110
+Own GWS MetaShares 30,gws_ms,1000,100,6110
+Own GWS MetaShares 30,gws_ms,5000,500,6110
+Own LuckyCat Metashares 25,lc_ms,10,1,6110
+Own LuckyCat Metashares 25,lc_ms,100,10,6110
+Own LuckyCat Metashares 25,lc_ms,1000,100,6110
+Own LuckyCat Metashares 25,lc_ms,5000,500,6110
+Own EternaLabs Metashares 31,el_ms,10,1,6110
+Own EternaLabs Metashares 31,el_ms,100,10,6110
+Own EternaLabs Metashares 31,el_ms,1000,100,6110
+Own EternaLabs Metashares 31,el_ms,5000,500,6110
+Own NetEmpire Metashares 27,ne_ms,10,1,6110
+Own NetEmpire Metashares 27,ne_ms,100,10,6110
+Own NetEmpire Metashares 27,ne_ms,1000,100,6110
+Own NetEmpire Metashares 27,ne_ms,5000,500,6110
+Own Gravity Grade MetaShares 26,gg_ms,10,1,6110
+Own Gravity Grade MetaShares 26,gg_ms,100,10,6110
+Own Gravity Grade MetaShares 26,gg_ms,1000,100,6110
+Own Gravity Grade MetaShares 26,gg_ms,5000,500,6110
+Own Newlands MetaShares 26,nl_ms,10,1,6110
+Own Newlands MetaShares 26,nl_ms,100,10,6110
+Own Newlands MetaShares 26,nl_ms,1000,100,6110
+Own Newlands MetaShares 26,nl_ms,5000,500,6110
+Own HaveBlue MetaShares 26,hb_ms,10,1,6110
+Own HaveBlue MetaShares 26,hb_ms,100,10,6110
+Own HaveBlue MetaShares 26,hb_ms,1000,100,6110
+Own HaveBlue MetaShares 26,hb_ms,5000,500,6110
+Own Arcades,arcades_owned,10,1,6110
+Own Arcades,arcades_owned,100,10,6110
+Own Arcades,arcades_owned,1000,100,6110
+Own Arcades,arcades_owned,5000,500,6110
+Own Unique Genesis NFT,genesis_unique_owned,100,1,3700
+Own Unique Genesis NFT,genesis_unique_owned,200,2,3700
+Own Unique Genesis NFT,genesis_unique_owned,300,3,3700
+Own Unique Genesis NFT,genesis_unique_owned,400,4,3700
+Own Unique Genesis NFT,genesis_unique_owned,500,5,3700
+Own Unique Genesis NFT,genesis_unique_owned,600,6,3700
+Own Unique Genesis NFT,genesis_unique_owned,700,7,3700
+Own Unique Genesis NFT,genesis_unique_owned,900,8,3700
+Mint Unique Genesis NFT,genesis_unique_mints,100,1,3700
+Mint Unique Genesis NFT,genesis_unique_mints,200,2,3700
+Mint Unique Genesis NFT,genesis_unique_mints,300,3,3700
+Mint Unique Genesis NFT,genesis_unique_mints,400,4,3700
+Mint Unique Genesis NFT,genesis_unique_mints,500,5,3700
+Mint Unique Genesis NFT,genesis_unique_mints,600,6,3700
+Mint Unique Genesis NFT,genesis_unique_mints,700,7,3700
+Mint Unique Genesis NFT,genesis_unique_mints,900,8,3700
+$IXT Speedup (hours),ixt_speedup_hours,25,25,5675
+$IXT Speedup (hours),ixt_speedup_hours,50,50,5675
+$IXT Speedup (hours),ixt_speedup_hours,100,100,5675
+$IXT Speedup (hours),ixt_speedup_hours,500,500,5675
+$IXT Speedup (hours),ixt_speedup_hours,5000,5000,5675
+AGOLD Streamed,spent_agold,100,5,13800
+AGOLD Streamed,spent_agold,200,10,13800
+AGOLD Streamed,spent_agold,500,25,13800
+AGOLD Streamed,spent_agold,1000,50,13800
+AGOLD Streamed,spent_agold,2000,100,13800
+AGOLD Streamed,spent_agold,10000,500,13800
+Participate in Normal Raffle 16,regular_raffle,10,1,360
+Participate in Normal Raffle 16,regular_raffle,100,10,360
+Participate in Normal Raffle 16,regular_raffle,250,25,360
+Participate in Ultra Raffle 17,premium_raffle,50,1,1800
+Participate in Ultra Raffle 17,premium_raffle,500,10,1800
+Participate in Ultra Raffle 17,premium_raffle,1250,25,1800
+Participate in Golden Raffle 18,golden_raffle,100,1,3600
+Participate in Golden Raffle 18,golden_raffle,1000,10,3600
+Participate in Golden Raffle 18,golden_raffle,2500,25,3600
+Create Order EL,prospecting_orders,50,100,2800
+Create Order EL,prospecting_orders,250,500,2800
+Create Order EL,prospecting_orders,2500,5000,2800
+Create Order GWS (per 25 waste),gws_orders,50,100,2800
+Create Order GWS (per 25 waste),gws_orders,250,500,2800
+Create Order GWS (per 25 waste),gws_orders,2500,5000,2800
+Facilty Minting,minted_facilities,50,1,5550
+Facilty Minting,minted_facilities,500,10,5550
+Facilty Minting,minted_facilities,5000,100,5550
+Farm Waste,waste_collected,100,500,1100
+Farm Waste,waste_collected,1000,5000,1100
+Energy Minted 24,energy_collected,50,100,5550
+Energy Minted 24,energy_collected,500,500,5550
+Energy Minted 24,energy_collected,5000,5000,5550
+Energy Burned 24,energy_burn,25,100,2775
+Energy Burned 24,energy_burn,250,500,2775
+Energy Burned 24,energy_burn,2500,5000,2775
+M3ta-m0d burned 0,meta_mod_burn,100,2,12600
+M3ta-m0d burned 0,meta_mod_burn,500,6,12600
+M3ta-m0d burned 0,meta_mod_burn,2000,10,12600
+M3ta-m0d burned 0,meta_mod_burn,10000,50,12600
+1 Month Staking (k),month_1,100,1,5600
+1 Month Staking (k),month_1,500,5,5600
+1 Month Staking (k),month_1,5000,100,5600
+3 Month Staking (k),month_3,200,1,11200
+3 Month Staking (k),month_3,1000,5,11200
+3 Month Staking (k),month_3,10000,100,11200
+6 Month Staking (k),month_6,400,1,22400
+6 Month Staking (k),month_6,2000,5,22400
+6 Month Staking (k),month_6,20000,100,22400
+12 Month Staking (k),month_12,800,1,44800
+12 Month Staking (k),month_12,4000,5,44800
+12 Month Staking (k),month_12,40000,100,44800
+LP Staking (k - USD),lp_usd_staked,100,1,5600
+LP Staking (k - USD),lp_usd_staked,500,5,5600
+LP Staking (k - USD),lp_usd_staked,5000,100,5600
diff --git a/requirements.txt b/requirements.txt
index e69de29b..2631462c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -0,0 +1,43 @@
+cachetools==5.3.0
+certifi==2022.12.7
+cffi==1.15.0
+charset-normalizer==3.1.0
+click==8.1.3
+colorama==0.4.6
+cryptography==36.0.1
+FileLock-git==0.1.0rc0
+Flask==2.2.3
+flask-starter==0.5.0
+google-api-core==2.11.0
+google-auth==2.17.3
+google-cloud-bigquery==3.9.0
+google-cloud-core==2.3.2
+google-crc32c==1.5.0
+google-resumable-media==2.4.1
+googleapis-common-protos==1.59.0
+grpcio==1.54.0
+grpcio-status==1.48.2
+gunicorn==20.1.0
+httplib2==0.22.0
+idna==3.4
+itsdangerous==2.1.2
+Jinja2==3.0.3
+MarkupSafe==2.1.2
+mysql-connector-python==8.0.33
+packaging==21.3
+proto-plus==1.22.2
+protobuf==3.20.3
+pyasn1==0.4.8
+pyasn1-modules==0.2.8
+pycparser==2.21
+pyfdlock==0.0.2
+pyparsing==3.0.7
+python-dateutil==2.8.2
+python-dotenv==1.0.0
+PyYAML==6.0
+requests==2.28.2
+resolvelib==0.5.4
+rsa==4.9
+six==1.16.0
+urllib3==1.26.15
+Werkzeug==2.2.3
diff --git a/runtime.txt b/runtime.txt
new file mode 100644
index 00000000..032aea2d
--- /dev/null
+++ b/runtime.txt
@@ -0,0 +1 @@
+python-3.9
\ No newline at end of file
diff --git a/server.py b/server.py
deleted file mode 100644
index 430d1dc7..00000000
--- a/server.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import os
-import http.server
-import socketserver
-
-from http import HTTPStatus
-
-
-class Handler(http.server.SimpleHTTPRequestHandler):
- def do_GET(self):
- self.send_response(HTTPStatus.OK)
- self.end_headers()
- msg = 'Hello! you requested %s' % (self.path)
- self.wfile.write(msg.encode())
-
-
-port = int(os.getenv('PORT', 80))
-print('Listening on port %s' % (port))
-httpd = socketserver.TCPServer(('', port), Handler)
-httpd.serve_forever()