Monday, November 25, 2024

Update: shared configuration files between client and server

Often the first step, in the sequence of developing a webapp, is to create a central description, i.e. a config file, which can act as a spine, as you add features and parameterize them.

It needs to be available to both your server code (in my current case Python 3.11 with Flask on Google App Engine), and the Javascript in any HTML file. If there are genuine and serious dials to be turned in the config file, both the client and server will typically be involved.

I wrote about this for an earlier, deprecated Google App Engine stack, here

So this is an update.

app.yaml

runtime: python311

app_engine_apis:
- url_fetch

handlers:
- url: /my_config.yaml
static_files: my_config.yaml
upload: my_config.yaml
secure: always

- url: /.*
script: auto
secure: always
redirect_http_response_code: 301

requirements.txt

flask
pyyaml
appengine-python-standard>=1.0.0
werkzeug==2.2.2

main.py

import yaml
from flask import Flask, Response, render_template, request

app = Flask(__name__)

# Load the YAML file at startup
with open('my_config.yaml', 'r') as file:
shared_data = yaml.safe_load(file)

@app.route('/')
def index():
return render_template('index.html')

@app.route('/api/shared-data')
def shared_data_api():
yaml_data = yaml.dump(shared_data)
return Response(yaml_data, mimetype='application/x-yaml')

if __name__ == '__main__':
app.run()

templates/index.html

<!DOCTYPE html>
<html>
<head>
<title>shared YAML example</title>
</head>
<body>
<h1>shared YAML example</h1>
<div id="output"></div>

<!-- Include js-yaml library -->
<script src="https://cdn.jsdelivr.net/npm/js-yaml@4/dist/js-yaml.min.js"></script>

<script>
// Fetch the YAML file directly
fetch('/my_config.yaml')
.then(response => response.text())
.then(yamlText => {
const data = jsyaml.load(yamlText);
console.log('Data from YAML file:', data);
})
.catch(error => console.error('Error fetching YAML file:', error));

// Fetch the YAML data from API endpoint
fetch('/api/shared-data')
.then(response => response.text())
.then(yamlText => {
const data = jsyaml.load(yamlText);
console.log('Data from API endpoint:', data);
const outputDiv = document.getElementById('output');
outputDiv.textContent = JSON.stringify(data, null, 2);
})
.catch(error => console.error('Error fetching YAML from API:', error));
</script>
</body>
</html>

my_config.yaml

application: google
        - this
        - could
        - be
        - anything


No comments: