Skip to content

Commit

Permalink
refactor: use pathlib.Path for file paths (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
uniqueg committed Jun 25, 2022
1 parent 54c6929 commit 8676b93
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 66 deletions.
4 changes: 2 additions & 2 deletions docs/api/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
from pathlib import Path
import sys

from sphinx.ext import apidoc

sys.path.insert(0, os.path.abspath('../..'))
sys.path.insert(0, Path.cwd().resolve().parents[1])


# -- Project information -----------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion foca/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

from foca.foca import Foca # noqa: F401

__version__ = '0.8.0'
__version__ = '0.9.0'
6 changes: 3 additions & 3 deletions foca/config/config_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ConfigParser():

def __init__(
self,
config_file: Optional[str] = None,
config_file: Optional[Path] = None,
custom_config_model: Optional[str] = None,
format_logs: bool = True
) -> None:
Expand Down Expand Up @@ -82,7 +82,7 @@ def _configure_logging(self) -> None:
)

@staticmethod
def parse_yaml(conf: str) -> Dict:
def parse_yaml(conf: Path) -> Dict:
"""Parse YAML file.
Args:
Expand All @@ -109,7 +109,7 @@ def parse_yaml(conf: str) -> Dict:
) from exc

@staticmethod
def merge_yaml(*args: str) -> Optional[Dict]:
def merge_yaml(*args: Path) -> Optional[Dict]:
"""Parse and merge a set of YAML files.
Merging is done iteratively, from the first, second to the n-th
Expand Down
9 changes: 6 additions & 3 deletions foca/foca.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Class for setting up and initializing a FOCA-based microservice."""

import logging
from pathlib import Path
from typing import Optional

from connexion import App
Expand All @@ -21,7 +22,7 @@ class Foca:

def __init__(
self,
config_file: Optional[str] = None,
config_file: Optional[Path] = None,
custom_config_model: Optional[str] = None,
) -> None:
"""Instantiate FOCA class.
Expand Down Expand Up @@ -58,8 +59,10 @@ def __init__(
parameters, so as to make it easier for others to
write/modify their app configuration.
"""
self.config_file = config_file
self.custom_config_model = custom_config_model
self.config_file: Optional[Path] = Path(
config_file
) if config_file is not None else None
self.custom_config_model: Optional[str] = custom_config_model

def create_app(self) -> App:
"""Set up and initialize FOCA-based microservice.
Expand Down
59 changes: 28 additions & 31 deletions foca/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import importlib
import operator
from pathlib import Path
import os
from typing import (Any, Dict, List, Optional, Union)

from pydantic import (BaseModel, Field, validator) # pylint: disable=E0611
Expand Down Expand Up @@ -532,9 +531,9 @@ class SpecConfig(FOCABaseConfig):
Example:
>>> SpecConfig(path="/my/path.yaml")
SpecConfig(path=['/my/path.yaml'], path_out='/my/path.modified.yaml', \
append=None, add_operation_fields=None, add_security_fields=None, disable_auth\
=False, connexion=None)
SpecConfig(path=[PosixPath('/my/path.yaml')], path_out=PosixPath('/my/\
path.modified.yaml'), append=None, add_operation_fields=None, add_security_fie\
lds=None, disable_auth=False, connexion=None)
>>> SpecConfig(
... path=["/path/to/specs.yaml", "/path/to/add_specs.yaml"],
Expand Down Expand Up @@ -563,16 +562,17 @@ class SpecConfig(FOCABaseConfig):
... },
... disable_auth = False
... )
SpecConfig(path=['/path/to/specs.yaml', '/path/to/add_specs.yaml'], pa\
th_out='/path/to/specs.modified.yaml', append=[{'security': {'jwt': {'type': '\
apiKey', 'name': 'Authorization', 'in': 'header'}}}, {'my_other_root_field': '\
some_value'}], add_operation_fields={'x-swagger-router-controller': 'controlle\
rs.my_specs', 'x-some-other-custom-field': 'some_value'}, add_security_fields=\
{'x-apikeyInfoFunc': 'security.auth.validate_token', 'x-some-other-custom-fiel\
d': 'some_value'}, disable_auth=False, connexion=None)
SpecConfig(path=[PosixPath('/path/to/specs.yaml'), PosixPath('/path/to\
/add_specs.yaml')], path_out=PosixPath('/path/to/specs.modified.yaml'), append\
=[{'security': {'jwt': {'type': 'apiKey', 'name': 'Authorization', 'in': 'head\
er'}}}, {'my_other_root_field': 'some_value'}], add_operation_fields={'x-swagg\
er-router-controller': 'controllers.my_specs', 'x-some-other-custom-field': 's\
ome_value'}, add_security_fields={'x-apikeyInfoFunc': 'security.auth.validate_\
token', 'x-some-other-custom-field': 'some_value'}, disable_auth=False, connex\
ion=None)
"""
path: Union[str, List[str]]
path_out: Optional[str] = None
path: Union[Path, List[Path]]
path_out: Optional[Path] = None
append: Optional[List[Dict]] = None
add_operation_fields: Optional[Dict] = None
add_security_fields: Optional[Dict] = None
Expand All @@ -585,16 +585,16 @@ def set_abs_path(cls, v): # pylint: disable=E0213
"""Resolve path relative to caller's current working directory if no
absolute path provided.
"""
# if path is a str, convert it to list
if(isinstance(v, str)):
if not Path(v).is_absolute():
return [str(Path.cwd() / v)]
# if path is not a list, convert it to single-item list
if(isinstance(v, Path)):
if not v.is_absolute():
return [Path.cwd() / v]
return [v]
else:
# modify each relaive part of the list
# make each path absolute
v = [
str(Path.cwd() / path)
if not Path(path).is_absolute()
Path.cwd() / path
if not path.is_absolute()
else path
for path in v
]
Expand All @@ -603,16 +603,13 @@ def set_abs_path(cls, v): # pylint: disable=E0213
# set default if no output file path provided
@validator('path_out', always=True, allow_reuse=True)
def set_default_out_path(cls, v, *, values): # pylint: disable=E0213
"""Set default output path for spec file if not supplied by user.
"""
"""Set default output path for spec file if not supplied by user."""
if 'path' in values and values['path'] is not None:
if not v:
return '.'.join([
os.path.splitext(values['path'][0])[0],
"modified.yaml"
])
if not Path(v).is_absolute():
return str(Path.cwd() / v)
path = values['path'][0]
return path.parent / f"{path.stem}.modified.yaml"
if not v.is_absolute():
return Path.cwd() / v
return v


Expand All @@ -636,9 +633,9 @@ class APIConfig(FOCABaseConfig):
>>> APIConfig(
... specs=[SpecConfig(path='/path/to/specs.yaml')],
... )
APIConfig(specs=[SpecConfig(path='/path/to/specs.yaml', path_out='/pat\
h/to/specs.modified.yaml', append=None, add_operation_fields=None, connexion=N\
one)])
APIConfig(specs=[SpecConfig(path=[PosixPath('/path/to/specs.yaml')], p\
ath_out=PosixPath('/path/to/specs.modified.yaml'), append=None, add_operation_\
fields=None, add_security_fields=None, disable_auth=False, connexion=None)])
"""
specs: List[SpecConfig] = []

Expand Down
21 changes: 10 additions & 11 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import os
"""Package setup."""

from pathlib import Path
from setuptools import setup, find_packages

root_dir = os.path.dirname(os.path.abspath(__file__))
root_dir = Path(__file__).parent.resolve()

# Read long description from file
file_name = os.path.join(root_dir, "README.md")
with open(file_name, "r") as fh:
long_description = fh.read()
file_name = root_dir / "README.md"
with open(file_name, "r") as _file:
long_description = _file.read()

# Read requirements from file
install_requires = []
req = root_dir + '/requirements.txt'
if os.path.isfile(req):
with open(req) as f:
install_requires = f.read().splitlines()
req = root_dir / 'requirements.txt'
with open(req, "r") as _file:
install_requires = _file.read().splitlines()

setup(
name="foca",
Expand Down
20 changes: 10 additions & 10 deletions tests/api/test_register_openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
from foca.models.config import SpecConfig

# Define mock data
DIR = Path(__file__).parent.parent / "test_files"
PATH_SPECS_2_YAML_ORIGINAL = str(DIR / "openapi_2_petstore.original.yaml")
PATH_SPECS_2_YAML_MODIFIED = str(DIR / "openapi_2_petstore.modified.yaml")
PATH_SPECS_2_JSON_ORIGINAL = str(DIR / "openapi_2_petstore.original.json")
PATH_SPECS_2_YAML_ADDITION = str(DIR / "openapi_2_petstore.addition.yaml")
PATH_SPECS_3_YAML_ORIGINAL = str(DIR / "openapi_3_petstore.original.yaml")
PATH_SPECS_3_YAML_MODIFIED = str(DIR / "openapi_3_petstore.modified.yaml")
PATH_SPECS_INVALID_JSON = str(DIR / "invalid.json")
PATH_SPECS_INVALID_YAML = str(DIR / "invalid.openapi.yaml")
PATH_NOT_FOUND = str(DIR / "does/not/exist.yaml")
DIR = Path(__file__).parents[1].resolve() / "test_files"
PATH_SPECS_2_YAML_ORIGINAL = DIR / "openapi_2_petstore.original.yaml"
PATH_SPECS_2_YAML_MODIFIED = DIR / "openapi_2_petstore.modified.yaml"
PATH_SPECS_2_JSON_ORIGINAL = DIR / "openapi_2_petstore.original.json"
PATH_SPECS_2_YAML_ADDITION = DIR / "openapi_2_petstore.addition.yaml"
PATH_SPECS_3_YAML_ORIGINAL = DIR / "openapi_3_petstore.original.yaml"
PATH_SPECS_3_YAML_MODIFIED = DIR / "openapi_3_petstore.modified.yaml"
PATH_SPECS_INVALID_JSON = DIR / "invalid.json"
PATH_SPECS_INVALID_YAML = DIR / "invalid.openapi.yaml"
PATH_NOT_FOUND = DIR / "does/not/exist.yaml"
OPERATION_FIELDS_2 = {"x-swagger-router-controller": "controllers"}
OPERATION_FIELDS_2_NO_RESOLVE = {"x-swagger-router-controller": YAMLError}
OPERATION_FIELDS_3 = {"x-openapi-router-controller": "controllers"}
Expand Down
6 changes: 3 additions & 3 deletions tests/models/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,19 +366,19 @@ def test_spec_config_list_no_out():
def test_SpecConfig_full():
"""Test SpecConfig instantiation; full example"""
res = SpecConfig(**SPEC_CONFIG)
assert res.path_out == SPEC_CONFIG['path_out']
assert str(res.path_out) == SPEC_CONFIG['path_out']


def test_SpecConfig_minimal():
"""Test SpecConfig instantiation; minimal example"""
res = SpecConfig(path=PATH)
assert res.path_out == PATH_MODIFIED
assert str(res.path_out) == PATH_MODIFIED


def test_SpecConfig_merge():
"""Test SpecConfig instantiation; multiple config files"""
res = SpecConfig(path=[PATH, PATH_ADDITION])
assert res.path_out == PATH_MODIFIED
assert str(res.path_out) == PATH_MODIFIED


def test_SpecConfig_extra_arg():
Expand Down
2 changes: 0 additions & 2 deletions tests/test_foca.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from pathlib import Path
import pytest
import shutil
import os

from connexion import App
from pydantic import ValidationError
Expand Down Expand Up @@ -101,7 +100,6 @@ def test_foca_api(tmpdir):
foca = Foca(config_file=temp_file)
app = foca.create_app()
assert isinstance(app, App)
os.remove(temp_file)


def test_foca_db():
Expand Down

0 comments on commit 8676b93

Please sign in to comment.