mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-11 17:10:57 +03:00
Add Github Navigator - Flask application
This commit is contained in:
parent
9afcd42633
commit
e8e878e623
6
examples/applications/ghnav-flask/config.yml
Normal file
6
examples/applications/ghnav-flask/config.yml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
github:
|
||||||
|
auth_token: ${GITHUB_TOKEN}
|
||||||
|
request_timeout: 10
|
||||||
|
search:
|
||||||
|
default_term: "Dependency Injector"
|
||||||
|
default_limit: 5
|
|
@ -0,0 +1,32 @@
|
||||||
|
"""Application module."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
from . import github, views, webapp
|
||||||
|
|
||||||
|
|
||||||
|
class Application(containers.DeclarativeContainer):
|
||||||
|
"""Application container."""
|
||||||
|
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
github_client = providers.Factory(
|
||||||
|
github.GitHubApiClient,
|
||||||
|
auth_token=config.github.auth_token,
|
||||||
|
request_timeout=config.github.request_timeout,
|
||||||
|
)
|
||||||
|
|
||||||
|
index_view = providers.Callable(
|
||||||
|
views.index,
|
||||||
|
github_client=github_client,
|
||||||
|
default_search_term=config.search.default_term,
|
||||||
|
default_search_limit=config.search.default_limit,
|
||||||
|
)
|
||||||
|
|
||||||
|
app = providers.Factory(
|
||||||
|
webapp.create_app,
|
||||||
|
name=__name__,
|
||||||
|
routes=[
|
||||||
|
webapp.Route('/', 'index', index_view, methods=['GET']),
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,8 @@
|
||||||
|
"""Entrypoint module."""
|
||||||
|
|
||||||
|
from .application import Application
|
||||||
|
|
||||||
|
|
||||||
|
application = Application()
|
||||||
|
application.config.from_yaml('config.yml')
|
||||||
|
app = application.app()
|
67
examples/applications/ghnav-flask/githubnavigator/github.py
Normal file
67
examples/applications/ghnav-flask/githubnavigator/github.py
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
"""Github API module."""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
class GitHubApiClient:
|
||||||
|
"""GitHub API client performs operations with Github API."""
|
||||||
|
|
||||||
|
API_URL = 'https://api.github.com/'
|
||||||
|
DEFAULT_LIMIT = 5
|
||||||
|
|
||||||
|
def __init__(self, auth_token, request_timeout):
|
||||||
|
"""Initialize search."""
|
||||||
|
self._auth_token = auth_token
|
||||||
|
self._request_timeout = request_timeout
|
||||||
|
|
||||||
|
def search_repositories(self, search_term, limit):
|
||||||
|
"""Search repositories."""
|
||||||
|
if not search_term:
|
||||||
|
return []
|
||||||
|
|
||||||
|
repositories = self._make_search('repositories', search_term, limit)
|
||||||
|
latest_commits = [
|
||||||
|
self._get_latest_commit(repository, search_term)
|
||||||
|
for repository in repositories
|
||||||
|
]
|
||||||
|
return list(zip(repositories, latest_commits))
|
||||||
|
|
||||||
|
def _make_search(self, entity, search_term, limit):
|
||||||
|
headers = {}
|
||||||
|
if self._auth_token:
|
||||||
|
headers['authorization'] = f'token {self._auth_token}'
|
||||||
|
|
||||||
|
response = requests.get(
|
||||||
|
url=f'{self.API_URL}search/{entity}',
|
||||||
|
params={
|
||||||
|
'q': f'{search_term} in:name',
|
||||||
|
'sort': 'updated',
|
||||||
|
'order': 'desc',
|
||||||
|
'page': 1,
|
||||||
|
'per_page': limit,
|
||||||
|
},
|
||||||
|
headers=headers,
|
||||||
|
timeout=self._request_timeout,
|
||||||
|
)
|
||||||
|
data = response.json()
|
||||||
|
return data['items']
|
||||||
|
|
||||||
|
def _get_latest_commit(self, repository, search_term):
|
||||||
|
headers = {}
|
||||||
|
if self._auth_token:
|
||||||
|
headers['authorization'] = f'token {self._auth_token}'
|
||||||
|
|
||||||
|
response = requests.get(
|
||||||
|
url=repository['commits_url'].replace('{/sha}', ''),
|
||||||
|
params={
|
||||||
|
'q': f'{search_term} in:name',
|
||||||
|
'sort': 'updated',
|
||||||
|
'order': 'desc',
|
||||||
|
'page': 1,
|
||||||
|
'per_page': 1,
|
||||||
|
},
|
||||||
|
headers=headers,
|
||||||
|
timeout=self._request_timeout,
|
||||||
|
)
|
||||||
|
data = response.json()
|
||||||
|
return data[0]
|
|
@ -0,0 +1,40 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Github Navigator</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Github Navigator</h1>
|
||||||
|
<form method="get">
|
||||||
|
<p>
|
||||||
|
Search term: <input type="text" name="search_term" value="{{ search_term if search_term }}">
|
||||||
|
Limit: <input type="text" name="limit" value="{{ limit }}">
|
||||||
|
<input type="submit">
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<h2>Search results</h2>
|
||||||
|
{% if repositories|length == 0 %}
|
||||||
|
<small>No search results</small>
|
||||||
|
{% endif %}
|
||||||
|
{% for repository, latest_commit in repositories %} {{n}}
|
||||||
|
<p>
|
||||||
|
<small>Search result # {{ loop.index }} from {{ repositories|length }}</small>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Repository: <a href="{{ repository['html_url'] }}">{{ repository['name'] }}</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Repository owner:
|
||||||
|
<a href="{{ repository['owner']['html_url'] }}"><img src="{{ repository['owner']['avatar_url'] }}" alt="avatar" height="24" width="24"/></a>
|
||||||
|
<a href="{{ repository['owner']['html_url'] }}">{{ repository['owner']['login'] }}</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Created at: {{ repository['created_at'] }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
LastCommit: <a href="{{ latest_commit['html_url'] }}">{{ latest_commit['sha'] }}</a> {{ latest_commit['commit']['message'] }} {{ latest_commit['commit']['author']['name'] }}
|
||||||
|
</p>
|
||||||
|
<hr/>
|
||||||
|
{% endfor %}
|
||||||
|
</body>
|
||||||
|
</html>
|
19
examples/applications/ghnav-flask/githubnavigator/views.py
Normal file
19
examples/applications/ghnav-flask/githubnavigator/views.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
"""Views module."""
|
||||||
|
|
||||||
|
from flask import request, render_template
|
||||||
|
|
||||||
|
from .github import GitHubApiClient
|
||||||
|
|
||||||
|
|
||||||
|
def index(github_client: GitHubApiClient, default_search_term, default_search_limit):
|
||||||
|
search_term = request.args.get('search_term', default_search_term)
|
||||||
|
limit = request.args.get('limit', default_search_limit)
|
||||||
|
|
||||||
|
repositories = github_client.search_repositories(search_term, limit)
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
'index.html',
|
||||||
|
search_term=search_term,
|
||||||
|
limit=limit,
|
||||||
|
repositories=repositories,
|
||||||
|
)
|
16
examples/applications/ghnav-flask/githubnavigator/webapp.py
Normal file
16
examples/applications/ghnav-flask/githubnavigator/webapp.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
"""Web application module."""
|
||||||
|
|
||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
|
||||||
|
def create_app(name, routes):
|
||||||
|
app = Flask(name)
|
||||||
|
for route in routes:
|
||||||
|
app.add_url_rule(*route.args, **route.kwargs)
|
||||||
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
class Route:
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.args = args
|
||||||
|
self.kwargs = kwargs
|
3
examples/applications/ghnav-flask/requirements.txt
Normal file
3
examples/applications/ghnav-flask/requirements.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
dependency-injector
|
||||||
|
flask
|
||||||
|
requests
|
Loading…
Reference in New Issue
Block a user