Skip to content

Commit

Permalink
Implemented everything except computations
Browse files Browse the repository at this point in the history
  • Loading branch information
Chelsea486MHz committed Jan 7, 2024
1 parent 5ad1fdc commit bdbc62b
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 18 deletions.
119 changes: 109 additions & 10 deletions compute/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@
# Initialize Flask
app = Flask(__name__)

# Simulation settings
timestep = 1e-12
gravity = 6.67408e-11
electrostatic = 8.9875517873681764e9 # 1 / (4 * pi * epsilon_0)

# Range of bodies to perform computations on
range_start = 0
range_end = 0

# List of bodies in the simulation
bodies = []


# Object describing a Stargazer body
class Body:
def __init__(self, position, velocity, acceleration, force, mass, electrostatic_charge):
self.position = position
self.velocity = velocity
self.acceleration = acceleration
self.force = force
self.mass = mass
self.electrostatic_charge = electrostatic_charge


# Register to the manager node
manager = os.environ.get('MANAGER_ENDPOINT')
print('Attempting registration with manager node at {}...'.format(manager))
Expand Down Expand Up @@ -58,71 +82,146 @@ def authenticate(request, type='any'):
def api_common_version():
with app.app_context():
if not authenticate(request):
return jsonify({'error': True}), 401
return jsonify({'success': False}), 401
return jsonify({'version': os.environ.get('STARGAZER_VERSION')}), 200


@app.route('/api/common/type', methods=['POST'])
def api_common_type():
with app.app_context():
if not authenticate(request):
return jsonify({'error': True}), 401
return jsonify({'success': False}), 401
return jsonify({'version': os.environ.get('STARGAZER_TYPE')}), 200


@app.route('/api/compute/update', methods=['POST'])
def api_compute_update():
if not authenticate(request, 'manager'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401

# Check if the bodies are provided
if not isinstance(request.json.get('bodies'), list):
return jsonify({'success': False}), 400

# Retrieve all bodies from the request
bodies = []
for body in request.json.get('bodies'):
position = body.get('position')
velocity = body.get('velocity')
acceleration = body.get('acceleration')
force = body.get('force')
mass = body.get('value').get('mass')
electrostatic_charge = body.get('value').get('electrostatic_charge')

# Check if the required data is provided
if not position or not velocity or not acceleration or not force or not mass or not electrostatic_charge:
return jsonify({'success': False}), 400

# Check if the data types are valid
if not isinstance(position, dict) or not isinstance(velocity, dict) or not isinstance(acceleration, dict) or not isinstance(force, dict) or not isinstance(mass, float) or not isinstance(electrostatic_charge, float):
return jsonify({'success': False}), 400

# Check if the vectors valid
if not isinstance(position.get('x'), float) or not isinstance(position.get('y'), float) or not isinstance(position.get('z'), float):
return jsonify({'success': False}), 400
if not isinstance(velocity.get('x'), float) or not isinstance(velocity.get('y'), float) or not isinstance(velocity.get('z'), float):
return jsonify({'success': False}), 400
if not isinstance(acceleration.get('x'), float) or not isinstance(acceleration.get('y'), float) or not isinstance(acceleration.get('z'), float):
return jsonify({'success': False}), 400
if not isinstance(force.get('x'), float) or not isinstance(force.get('y'), float) or not isinstance(force.get('z'), float):
return jsonify({'success': False}), 400

# Create vectors from the retrieved variables
position = [position.get('x'), position.get('y'), position.get('z')]
velocity = [velocity.get('x'), velocity.get('y'), velocity.get('z')]
acceleration = [acceleration.get('x'), acceleration.get('y'), acceleration.get('z')]
force = [force.get('x'), force.get('y'), force.get('z')]

# Create the body
bodies.append(Body(position, velocity, acceleration, force, mass, electrostatic_charge))

return jsonify({'success': True}), 200


@app.route('/api/compute/configure', methods=['POST'])
def api_compute_configure():
if not authenticate(request, 'manager'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401

# Retrieve the variables from the request
timestep = request.json.get('constants').get('timestep')
gravity = request.json.get('constants').get('gravity')
electrostatic = request.json.get('constants').get('electrostatic')

# Check if the variables are provided
if not timestep or not gravity or not electrostatic:
return jsonify({'success': False}), 400

# Check if the variables are valid
if not isinstance(timestep, float) or not isinstance(gravity, float) or not isinstance(electrostatic, float):
return jsonify({'success': False}), 400
if timestep <= 0:
return jsonify({'success': False}), 400

return jsonify({'success': True}), 200


@app.route('/api/compute/assign', methods=['POST'])
def api_compute_assign():
if not authenticate(request, 'manager'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401

# Retrieve the range from the request
range_start = request.json.get('range').get('start')
range_end = request.json.get('range').get('end')

# Check if the range is provided
if not range_start or not range_end:
return jsonify({'success': False}), 400

# Check if the range is valid
if not isinstance(range_start, int) or not isinstance(range_end, int):
return jsonify({'success': False}), 400
if range_start < 0 or range_end < 0:
return jsonify({'success': False}), 400
if range_start > range_end:
return jsonify({'success': False}), 400

return jsonify({'success': True}), 200


@app.route('/api/compute/potential/gravity', methods=['POST'])
def api_compute_potential_gravity():
if not authenticate(request, 'manager'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401
return jsonify({'success': True}), 200


@app.route('/api/compute/potential/electrostatic', methods=['POST'])
def api_compute_potential_electrostatic():
if not authenticate(request, 'manager'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401
return jsonify({'success': True}), 200


@app.route('/api/compute/force/gravity', methods=['POST'])
def api_compute_force_gravity():
if not authenticate(request, 'manager'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401
return jsonify({'success': True}), 200


@app.route('/api/compute/force/electrostatic', methods=['POST'])
def api_compute_force_electrostatic():
if not authenticate(request, 'manager'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401
return jsonify({'success': True}), 200


@app.route('/api/compute/integrate', methods=['POST'])
def api_compute_integrate():
if not authenticate(request, 'manager'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401
return jsonify({'success': True}), 200


Expand Down
2 changes: 1 addition & 1 deletion docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ All Stargazer API calls require token authentication. To known which token type

`$MANAGER_TOKEN`: manager tokens.

When response data is not documented, it means the call returns either `"success"` or `"failure"` depending on what happened.
When response data is not documented, it means the call returns either `{success: False}` or `{success: True}` depending on what happened.

## Authentication

Expand Down
2 changes: 0 additions & 2 deletions docs/user-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,3 @@

---



149 changes: 144 additions & 5 deletions manager/app.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
from flask import Flask, request, jsonify
import requests
import hashlib
import os

# Initialize Flask
app = Flask(__name__)

# Table of registered compute nodes
# First element is the token hash
# Second element is the compute node's URI
registered = []

# Simulation settings
timestep = 1e-12
gravity = 6.67408e-11
electrostatic = 8.9875517873681764e9 # 1 / (4 * pi * epsilon_0)

# List of bodies in the simulation
bodies = []


# Object describing a Stargazer body
class Body:
def __init__(self, position, velocity, acceleration, force, mass, electrostatic_charge):
self.position = position
self.velocity = velocity
self.acceleration = acceleration
self.force = force
self.mass = mass
self.electrostatic_charge = electrostatic_charge


def authenticate(request, type='any'):
# Convert type to integer
Expand Down Expand Up @@ -61,28 +86,142 @@ def api_common_type():
@app.route('/api/manager/register', methods=['POST'])
def api_manager_register():
if not authenticate(request, 'compute'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401

# Get the compute node's URI
uri = request.json.get('compute_endpoint')

# Check if the URI is provided and valid
if not uri:
return jsonify({'success': False}), 400
if not uri.startswith('http://') and not uri.startswith('https://'):
return jsonify({'success': False}), 400

# Hash the token
token = request.headers.get('Authorization')
token = hashlib.sha256(token.split(' ')[1].encode('utf-8')).hexdigest()

# Check if the compute node token is already registered
for node in registered:
if node[0] == token:
return jsonify({'success': False}), 409

# Check if the compute node URI is already registered
for node in registered:
if node[1] == uri:
return jsonify({'success': False}), 409

# Register the node
registered.append([token, uri])

return jsonify({'success': True}), 200


@app.route('/api/manager/unregister', methods=['POST'])
def api_manager_unregister():
if not authenticate(request, 'compute'):
return 'Unauthorized', 401
return jsonify({'success': True}), 200
return jsonify({'success': False}), 401

# Hash the token
token = request.headers.get('Authorization')
token = hashlib.sha256(token.split(' ')[1].encode('utf-8')).hexdigest()

# Check if the compute node token is registered
for node in registered:
if node[0] == token:
registered.remove(node)
return jsonify({'success': True}), 200

return jsonify({'success': False}), 404


@app.route('/api/manager/configure', methods=['POST'])
def api_manager_configure():
if not authenticate(request, 'user'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401

# Retrieve the variables from the request
timestep = request.json.get('constants').get('timestep')
gravity = request.json.get('constants').get('gravity')
electrostatic = request.json.get('constants').get('electrostatic')
bodies = request.json.get('bodies')

# Check if the variables are provided
if not timestep or not gravity or not electrostatic or not bodies:
return jsonify({'success': False}), 400

# Check if the variables are valid
if not isinstance(timestep, float) or not isinstance(gravity, float) or not isinstance(electrostatic, float):
return jsonify({'success': False}), 400

# Check if the bodies are provided
if not isinstance(bodies, list):
return jsonify({'success': False}), 400

# Retrieve all bodies from the request
bodies = []
for body in request.json.get('bodies'):
position = body.get('position')
velocity = body.get('velocity')
acceleration = body.get('acceleration')
force = body.get('force')
mass = body.get('value').get('mass')
electrostatic_charge = body.get('value').get('electrostatic_charge')

# Check if the required data is provided
if not position or not velocity or not acceleration or not force or not mass or not electrostatic_charge:
return jsonify({'success': False}), 400

# Check if the data types are valid
if not isinstance(position, dict) or not isinstance(velocity, dict) or not isinstance(acceleration, dict) or not isinstance(force, dict) or not isinstance(mass, float) or not isinstance(electrostatic_charge, float):
return jsonify({'success': False}), 400

# Check if the timestep is valid
if timestep <= 0:
return jsonify({'success': False}), 400

# Check if the vectors valid
if not isinstance(position.get('x'), float) or not isinstance(position.get('y'), float) or not isinstance(position.get('z'), float):
return jsonify({'success': False}), 400
if not isinstance(velocity.get('x'), float) or not isinstance(velocity.get('y'), float) or not isinstance(velocity.get('z'), float):
return jsonify({'success': False}), 400
if not isinstance(acceleration.get('x'), float) or not isinstance(acceleration.get('y'), float) or not isinstance(acceleration.get('z'), float):
return jsonify({'success': False}), 400
if not isinstance(force.get('x'), float) or not isinstance(force.get('y'), float) or not isinstance(force.get('z'), float):
return jsonify({'success': False}), 400

# Create vectors from the retrieved variables
position = [position.get('x'), position.get('y'), position.get('z')]
velocity = [velocity.get('x'), velocity.get('y'), velocity.get('z')]
acceleration = [acceleration.get('x'), acceleration.get('y'), acceleration.get('z')]
force = [force.get('x'), force.get('y'), force.get('z')]

# Create the body
bodies.append(Body(position, velocity, acceleration, force, mass, electrostatic_charge))

return jsonify({'success': True}), 200


@app.route('/api/manager/simulate', methods=['POST'])
def api_manager_simulate():
if not authenticate(request, 'user'):
return 'Unauthorized', 401
return jsonify({'success': False}), 401

# Retrieve the duration from the request
duration = request.json.get('duration')

# Check if the duration is provided
if not duration:
return jsonify({'success': False}), 400

# Check if the duration is valid
if not isinstance(duration, float):
return jsonify({'success': False}), 400
if duration <= 0:
return jsonify({'success': False}), 400

# Simulate the universe

return jsonify({'success': True}), 200


Expand Down

0 comments on commit bdbc62b

Please sign in to comment.