Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using FOCA without Docker #209

Open
paras41617 opened this issue Apr 1, 2024 · 4 comments
Open

Using FOCA without Docker #209

paras41617 opened this issue Apr 1, 2024 · 4 comments
Labels
priority: medium Medium priority status: blocked Something prevents progress type: maintenance Related to general repository maintenance workload: hours Likely takes hours to resolve
Milestone

Comments

@paras41617
Copy link

Problem

When trying to use FOCA without using docker container, the below error is arising.
image (1)

Steps to recreate

  1. create a virtualenv using virtualenv venv and activate it using venv\scripts\activate.
  2. Install foca package using pip install foca.
  3. Create app.py file and add the following code in it.
   from foca import Foca
   if __name__ == '__main__':
   foca = Foca(
       config_file="config.yaml"
   )
   app = foca.create_app()
   app.run()
  1. create a config.yaml file and add the following code in it.
    server:
    host: '0.0.0.0'
    port: 8080
    debug: True
    environment: development
    testing: False
    use_reloader: True```
  1. 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 again python app.py and it will work.
@uniqueg
Copy link
Member

uniqueg commented May 18, 2024

Thanks for the detailed report, @paras41617 🙏 We need to do some maintenance work first because currently our tests are failing on the head commit. We will look into it afterwards.

@uniqueg uniqueg added this to the v1.0.0 milestone May 20, 2024
@uniqueg uniqueg added priority: medium Medium priority type: maintenance Related to general repository maintenance workload: hours Likely takes hours to resolve status: blocked Something prevents progress labels May 20, 2024
@uniqueg
Copy link
Member

uniqueg commented May 20, 2024

Currently blocked by #188

@JaeAeich
Copy link

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.pyboth 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:

  • If foca restricts config to only absolute path (which I don't think is ideal).
  • Consumers of foca should use jinja templating to create a temporary config files. This IMO solves another imp problem of setting up a dev env. Lets say I wanted to test my API with my mongo atlas, but my prod should be a 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()

@uniqueg
Copy link
Member

uniqueg commented May 24, 2024

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: medium Medium priority status: blocked Something prevents progress type: maintenance Related to general repository maintenance workload: hours Likely takes hours to resolve
Projects
Status: Todo other
Development

No branches or pull requests

3 participants