Open paras41617 opened 8 months ago
Thanks for the detailed report, @paras41617 :pray: We need to do some maintenance work first because currently our tests are failing on the head commit. We will look into it afterwards.
Currently blocked by #188
TL;DR: relative path causing issues, check this fix.
@uniqueg
The issue (well not really an issue), is that configs use relative paths.
api
- app.py
- models.py
- ...
- ...
- config.yaml
Lets say you have the above str, if you run app.py
from inside the api
dir and outside with `python3 api/app.py
both will yield diff results, as most probably config written wrt $(pwd)/api/
(because we decided to pu config in api dir).
All you need to do is be consistent with how you envoke app.py
in Dockerfile
and in local machine.
There could be a 2 better way to deal with this:
foca
restricts config to only absolute path (which I don't think is ideal).pod
or a container
. This would make more sense and be less pain to inject values in jinja
. Take a look at below.# config.yaml
database:
host: {% if environment == "prod" %}prod.db.example.com{% else %}dev.db.example.com{% endif %}
username: {% if environment == "prod" %}prod_user{% else %}dev_user{% endif %}
password: {% if environment == "prod" %}prod_password{% else %}dev_password{% endif %}
port: {{ db_port }}
from jinja2 import Environment, FileSystemLoader
import os
from pathlib import Path
import tempfile
def main():
config_path = Path(__file__).parent / "config.yaml"
if not config_path.exists():
raise FileNotFoundError(f"Config file not found: {config_path}")
environment = os.getenv('ENV', 'dev') # Default to 'dev' if ENV is not set
db_port = os.getenv('DB_PORT', '5432') # Default to '5432' if DB_PORT is not set
env = Environment(loader=FileSystemLoader(config_path.parent))
template = env.get_template(config_path.name)
rendered_config = template.render(environment=environment, db_port=db_port)
# Create a temporary config file with the rendered template
with tempfile.NamedTemporaryFile(delete=False, suffix='.yaml') as tmp_config_file:
tmp_config_file.write(rendered_config.encode())
tmp_config_path = tmp_config_file.name
# Create app object using the temporary config file
foca = Foca(
config_file=tmp_config_path,
custom_config_model="service_models.custom_config.CustomConfig",
)
foca.config_file
app = foca.create_app()
# Optionally delete the temporary file after creating the app
os.remove(tmp_config_path)
if __name__ == "__main__":
main()
Thanks @JaeAeich.
I think there are other options as well, e.g., anchoring the relative path not to the caller's current working directory, but to some other reference, e.g., the repository root path. I will take care of that when refactoring FOCA.
I will think about the templating suggestion as well (another good point), though I feel that that is another issue. We should probably take the config.yaml
files out of the code package and put them in deployment/
, together with the docker-compose.yml
files. We could then also think about creating a config map in Kubernetes, so that params can be adjusted on running services (another long-standing open issue).
Problem
When trying to use FOCA without using docker container, the below error is arising.
Steps to recreate
1) create a virtualenv using
virtualenv venv
and activate it usingvenv\scripts\activate
. 2) Install foca package usingpip install foca
. 3) Create app.py file and add the following code in it.4) create a config.yaml file and add the following code in it.
5) Run
python app.py
Workaround
1) Create a requirements.txt file in the folder where your app.py is present. 2) Copy all the packages from this file and paste it into your requirements.txt file (just copy all and paste). 3) Run
python install -r requirements.txt
. 4) Now start againpython app.py
and it will work.