Skip to content

Commit

Permalink
Endpoints won't be reloaded if endpoints.yaml has not been changed
Browse files Browse the repository at this point in the history
Added .pydocstyle
Added .dockerignore
Refactored utils
Add tests
  • Loading branch information
Umut Seven committed Feb 10, 2021
1 parent e4ce7be commit 7c9d144
Show file tree
Hide file tree
Showing 15 changed files with 337 additions and 11 deletions.
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
*.log
.git
7 changes: 7 additions & 0 deletions .idea/apyr.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/pylint.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions .idea/webResources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .pydocstyle
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pydocstyle]
inherit = false
ignore = D100,D101,D102,D103,D104,D107,D213
match = .*\.py
31 changes: 25 additions & 6 deletions apyr/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from pathlib import Path
from typing import List

import names
Expand All @@ -6,7 +7,7 @@

from apyr.exceptions import TooManyEndpointsException, NoEndpointsException
from apyr.models import ContentFunction, Endpoint
from apyr.utils import get_project_root
from apyr.utils import get_project_root, get_digest

FUNCTIONS = [
ContentFunction(name="random_first_name", returns=names.get_first_name),
Expand All @@ -16,15 +17,19 @@

class EndpointsRepo:

def __init__(self):
self.last_hash: str = ""
self.endpoints: List[Endpoint] = []
self.endpoints_path = get_project_root().joinpath("endpoints.yaml")

def _load_endpoints(self):
base_dir = get_project_root()
endpoints_path = base_dir.joinpath("endpoints.yaml")
stream = open(endpoints_path, "r")
stream = open(self.endpoints_path, "r")
endpoints = yaml.full_load(stream)

self.endpoints = [Endpoint(**endpoint) for endpoint in endpoints]

def _check_for_functions(self, content: str) -> str:
@staticmethod
def _check_for_functions(content: str) -> str:
for function in FUNCTIONS:
full_fun_name = f"%{function.name}%"
if full_fun_name in content:
Expand All @@ -33,8 +38,22 @@ def _check_for_functions(self, content: str) -> str:

return content

def _check_if_file_changed(self, path: Path) -> bool:
"""Check to see if the file changed.
We hash the file and compare it to the previous hash.
"""
new_hash = get_digest(str(path))
if new_hash != self.last_hash:
self.last_hash = new_hash
return True

return False

def get_response(self, path: str, method: str) -> Response:
self._load_endpoints()
# Do not reload endpoints if the file has not changed
if self._check_if_file_changed(self.endpoints_path):
self._load_endpoints()

def _filter_endpoints(endpoint: Endpoint):
return endpoint.path == path and endpoint.method.lower() == method.lower()
Expand Down
2 changes: 0 additions & 2 deletions apyr/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@


def run():
"""Mock that API!"""

uvicorn.run(app, host="0.0.0.0", port=8000)


Expand Down
9 changes: 8 additions & 1 deletion apyr/routers/endpoints.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from functools import lru_cache

from fastapi import APIRouter, Depends, Request, HTTPException

from apyr.dependencies import EndpointsRepo
Expand All @@ -6,6 +8,11 @@
endpoint_router = APIRouter()


@lru_cache
def endpoints_dependency() -> EndpointsRepo:
return EndpointsRepo()


@endpoint_router.get("/{path:path}")
@endpoint_router.head("/{path:path}")
@endpoint_router.post("/{path:path}")
Expand All @@ -15,7 +22,7 @@
@endpoint_router.trace("/{path:path}")
@endpoint_router.patch("/{path:path}")
async def all_endpoints(
path: str, request: Request, repo: EndpointsRepo = Depends(EndpointsRepo)
path: str, request: Request, repo: EndpointsRepo = Depends(endpoints_dependency)
):
try:
response = repo.get_response(path, request.method)
Expand Down
14 changes: 14 additions & 0 deletions apyr/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import hashlib
from pathlib import Path


def get_project_root() -> Path:
return Path(__file__).parent.parent


def get_digest(file_path: str) -> str:
hash_256 = hashlib.sha256()

with open(file_path, "rb") as file:
while True:
chunk = file.read(hash_256.block_size)
if not chunk:
break
hash_256.update(chunk)

return hash_256.hexdigest()
Loading

0 comments on commit 7c9d144

Please sign in to comment.