Skip to content

Commit 8676b93

Browse files
authored
refactor: use pathlib.Path for file paths (#134)
1 parent 54c6929 commit 8676b93

File tree

9 files changed

+63
-66
lines changed

9 files changed

+63
-66
lines changed

docs/api/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
# add these directories to sys.path here. If the directory is relative to the
1313
# documentation root, use os.path.abspath to make it absolute, like shown here.
1414
#
15-
import os
15+
from pathlib import Path
1616
import sys
1717

1818
from sphinx.ext import apidoc
1919

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

2222

2323
# -- Project information -----------------------------------------------------

foca/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
from foca.foca import Foca # noqa: F401
44

5-
__version__ = '0.8.0'
5+
__version__ = '0.9.0'

foca/config/config_parser.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class ConfigParser():
4949

5050
def __init__(
5151
self,
52-
config_file: Optional[str] = None,
52+
config_file: Optional[Path] = None,
5353
custom_config_model: Optional[str] = None,
5454
format_logs: bool = True
5555
) -> None:
@@ -82,7 +82,7 @@ def _configure_logging(self) -> None:
8282
)
8383

8484
@staticmethod
85-
def parse_yaml(conf: str) -> Dict:
85+
def parse_yaml(conf: Path) -> Dict:
8686
"""Parse YAML file.
8787
8888
Args:
@@ -109,7 +109,7 @@ def parse_yaml(conf: str) -> Dict:
109109
) from exc
110110

111111
@staticmethod
112-
def merge_yaml(*args: str) -> Optional[Dict]:
112+
def merge_yaml(*args: Path) -> Optional[Dict]:
113113
"""Parse and merge a set of YAML files.
114114
115115
Merging is done iteratively, from the first, second to the n-th

foca/foca.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Class for setting up and initializing a FOCA-based microservice."""
22

33
import logging
4+
from pathlib import Path
45
from typing import Optional
56

67
from connexion import App
@@ -21,7 +22,7 @@ class Foca:
2122

2223
def __init__(
2324
self,
24-
config_file: Optional[str] = None,
25+
config_file: Optional[Path] = None,
2526
custom_config_model: Optional[str] = None,
2627
) -> None:
2728
"""Instantiate FOCA class.
@@ -58,8 +59,10 @@ def __init__(
5859
parameters, so as to make it easier for others to
5960
write/modify their app configuration.
6061
"""
61-
self.config_file = config_file
62-
self.custom_config_model = custom_config_model
62+
self.config_file: Optional[Path] = Path(
63+
config_file
64+
) if config_file is not None else None
65+
self.custom_config_model: Optional[str] = custom_config_model
6366

6467
def create_app(self) -> App:
6568
"""Set up and initialize FOCA-based microservice.

foca/models/config.py

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import importlib
77
import operator
88
from pathlib import Path
9-
import os
109
from typing import (Any, Dict, List, Optional, Union)
1110

1211
from pydantic import (BaseModel, Field, validator) # pylint: disable=E0611
@@ -532,9 +531,9 @@ class SpecConfig(FOCABaseConfig):
532531
Example:
533532
534533
>>> SpecConfig(path="/my/path.yaml")
535-
SpecConfig(path=['/my/path.yaml'], path_out='/my/path.modified.yaml', \
536-
append=None, add_operation_fields=None, add_security_fields=None, disable_auth\
537-
=False, connexion=None)
534+
SpecConfig(path=[PosixPath('/my/path.yaml')], path_out=PosixPath('/my/\
535+
path.modified.yaml'), append=None, add_operation_fields=None, add_security_fie\
536+
lds=None, disable_auth=False, connexion=None)
538537
539538
>>> SpecConfig(
540539
... path=["/path/to/specs.yaml", "/path/to/add_specs.yaml"],
@@ -563,16 +562,17 @@ class SpecConfig(FOCABaseConfig):
563562
... },
564563
... disable_auth = False
565564
... )
566-
SpecConfig(path=['/path/to/specs.yaml', '/path/to/add_specs.yaml'], pa\
567-
th_out='/path/to/specs.modified.yaml', append=[{'security': {'jwt': {'type': '\
568-
apiKey', 'name': 'Authorization', 'in': 'header'}}}, {'my_other_root_field': '\
569-
some_value'}], add_operation_fields={'x-swagger-router-controller': 'controlle\
570-
rs.my_specs', 'x-some-other-custom-field': 'some_value'}, add_security_fields=\
571-
{'x-apikeyInfoFunc': 'security.auth.validate_token', 'x-some-other-custom-fiel\
572-
d': 'some_value'}, disable_auth=False, connexion=None)
565+
SpecConfig(path=[PosixPath('/path/to/specs.yaml'), PosixPath('/path/to\
566+
/add_specs.yaml')], path_out=PosixPath('/path/to/specs.modified.yaml'), append\
567+
=[{'security': {'jwt': {'type': 'apiKey', 'name': 'Authorization', 'in': 'head\
568+
er'}}}, {'my_other_root_field': 'some_value'}], add_operation_fields={'x-swagg\
569+
er-router-controller': 'controllers.my_specs', 'x-some-other-custom-field': 's\
570+
ome_value'}, add_security_fields={'x-apikeyInfoFunc': 'security.auth.validate_\
571+
token', 'x-some-other-custom-field': 'some_value'}, disable_auth=False, connex\
572+
ion=None)
573573
"""
574-
path: Union[str, List[str]]
575-
path_out: Optional[str] = None
574+
path: Union[Path, List[Path]]
575+
path_out: Optional[Path] = None
576576
append: Optional[List[Dict]] = None
577577
add_operation_fields: Optional[Dict] = None
578578
add_security_fields: Optional[Dict] = None
@@ -585,16 +585,16 @@ def set_abs_path(cls, v): # pylint: disable=E0213
585585
"""Resolve path relative to caller's current working directory if no
586586
absolute path provided.
587587
"""
588-
# if path is a str, convert it to list
589-
if(isinstance(v, str)):
590-
if not Path(v).is_absolute():
591-
return [str(Path.cwd() / v)]
588+
# if path is not a list, convert it to single-item list
589+
if(isinstance(v, Path)):
590+
if not v.is_absolute():
591+
return [Path.cwd() / v]
592592
return [v]
593593
else:
594-
# modify each relaive part of the list
594+
# make each path absolute
595595
v = [
596-
str(Path.cwd() / path)
597-
if not Path(path).is_absolute()
596+
Path.cwd() / path
597+
if not path.is_absolute()
598598
else path
599599
for path in v
600600
]
@@ -603,16 +603,13 @@ def set_abs_path(cls, v): # pylint: disable=E0213
603603
# set default if no output file path provided
604604
@validator('path_out', always=True, allow_reuse=True)
605605
def set_default_out_path(cls, v, *, values): # pylint: disable=E0213
606-
"""Set default output path for spec file if not supplied by user.
607-
"""
606+
"""Set default output path for spec file if not supplied by user."""
608607
if 'path' in values and values['path'] is not None:
609608
if not v:
610-
return '.'.join([
611-
os.path.splitext(values['path'][0])[0],
612-
"modified.yaml"
613-
])
614-
if not Path(v).is_absolute():
615-
return str(Path.cwd() / v)
609+
path = values['path'][0]
610+
return path.parent / f"{path.stem}.modified.yaml"
611+
if not v.is_absolute():
612+
return Path.cwd() / v
616613
return v
617614

618615

@@ -636,9 +633,9 @@ class APIConfig(FOCABaseConfig):
636633
>>> APIConfig(
637634
... specs=[SpecConfig(path='/path/to/specs.yaml')],
638635
... )
639-
APIConfig(specs=[SpecConfig(path='/path/to/specs.yaml', path_out='/pat\
640-
h/to/specs.modified.yaml', append=None, add_operation_fields=None, connexion=N\
641-
one)])
636+
APIConfig(specs=[SpecConfig(path=[PosixPath('/path/to/specs.yaml')], p\
637+
ath_out=PosixPath('/path/to/specs.modified.yaml'), append=None, add_operation_\
638+
fields=None, add_security_fields=None, disable_auth=False, connexion=None)])
642639
"""
643640
specs: List[SpecConfig] = []
644641

setup.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
import os
1+
"""Package setup."""
2+
3+
from pathlib import Path
24
from setuptools import setup, find_packages
35

4-
root_dir = os.path.dirname(os.path.abspath(__file__))
6+
root_dir = Path(__file__).parent.resolve()
57

6-
# Read long description from file
7-
file_name = os.path.join(root_dir, "README.md")
8-
with open(file_name, "r") as fh:
9-
long_description = fh.read()
8+
file_name = root_dir / "README.md"
9+
with open(file_name, "r") as _file:
10+
long_description = _file.read()
1011

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

1817
setup(
1918
name="foca",

tests/api/test_register_openapi.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@
1414
from foca.models.config import SpecConfig
1515

1616
# Define mock data
17-
DIR = Path(__file__).parent.parent / "test_files"
18-
PATH_SPECS_2_YAML_ORIGINAL = str(DIR / "openapi_2_petstore.original.yaml")
19-
PATH_SPECS_2_YAML_MODIFIED = str(DIR / "openapi_2_petstore.modified.yaml")
20-
PATH_SPECS_2_JSON_ORIGINAL = str(DIR / "openapi_2_petstore.original.json")
21-
PATH_SPECS_2_YAML_ADDITION = str(DIR / "openapi_2_petstore.addition.yaml")
22-
PATH_SPECS_3_YAML_ORIGINAL = str(DIR / "openapi_3_petstore.original.yaml")
23-
PATH_SPECS_3_YAML_MODIFIED = str(DIR / "openapi_3_petstore.modified.yaml")
24-
PATH_SPECS_INVALID_JSON = str(DIR / "invalid.json")
25-
PATH_SPECS_INVALID_YAML = str(DIR / "invalid.openapi.yaml")
26-
PATH_NOT_FOUND = str(DIR / "does/not/exist.yaml")
17+
DIR = Path(__file__).parents[1].resolve() / "test_files"
18+
PATH_SPECS_2_YAML_ORIGINAL = DIR / "openapi_2_petstore.original.yaml"
19+
PATH_SPECS_2_YAML_MODIFIED = DIR / "openapi_2_petstore.modified.yaml"
20+
PATH_SPECS_2_JSON_ORIGINAL = DIR / "openapi_2_petstore.original.json"
21+
PATH_SPECS_2_YAML_ADDITION = DIR / "openapi_2_petstore.addition.yaml"
22+
PATH_SPECS_3_YAML_ORIGINAL = DIR / "openapi_3_petstore.original.yaml"
23+
PATH_SPECS_3_YAML_MODIFIED = DIR / "openapi_3_petstore.modified.yaml"
24+
PATH_SPECS_INVALID_JSON = DIR / "invalid.json"
25+
PATH_SPECS_INVALID_YAML = DIR / "invalid.openapi.yaml"
26+
PATH_NOT_FOUND = DIR / "does/not/exist.yaml"
2727
OPERATION_FIELDS_2 = {"x-swagger-router-controller": "controllers"}
2828
OPERATION_FIELDS_2_NO_RESOLVE = {"x-swagger-router-controller": YAMLError}
2929
OPERATION_FIELDS_3 = {"x-openapi-router-controller": "controllers"}

tests/models/test_config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -366,19 +366,19 @@ def test_spec_config_list_no_out():
366366
def test_SpecConfig_full():
367367
"""Test SpecConfig instantiation; full example"""
368368
res = SpecConfig(**SPEC_CONFIG)
369-
assert res.path_out == SPEC_CONFIG['path_out']
369+
assert str(res.path_out) == SPEC_CONFIG['path_out']
370370

371371

372372
def test_SpecConfig_minimal():
373373
"""Test SpecConfig instantiation; minimal example"""
374374
res = SpecConfig(path=PATH)
375-
assert res.path_out == PATH_MODIFIED
375+
assert str(res.path_out) == PATH_MODIFIED
376376

377377

378378
def test_SpecConfig_merge():
379379
"""Test SpecConfig instantiation; multiple config files"""
380380
res = SpecConfig(path=[PATH, PATH_ADDITION])
381-
assert res.path_out == PATH_MODIFIED
381+
assert str(res.path_out) == PATH_MODIFIED
382382

383383

384384
def test_SpecConfig_extra_arg():

tests/test_foca.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from pathlib import Path
44
import pytest
55
import shutil
6-
import os
76

87
from connexion import App
98
from pydantic import ValidationError
@@ -101,7 +100,6 @@ def test_foca_api(tmpdir):
101100
foca = Foca(config_file=temp_file)
102101
app = foca.create_app()
103102
assert isinstance(app, App)
104-
os.remove(temp_file)
105103

106104

107105
def test_foca_db():

0 commit comments

Comments
 (0)