mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-01-31 03:36:41 +03:00
Merge branch 'release/3.23.0' into master
This commit is contained in:
commit
cfbed20a05
|
@ -103,8 +103,8 @@ the application structure. It is **easy to understand and change** it.
|
|||
index_view = flask.View(
|
||||
views.index,
|
||||
search_service=search_service,
|
||||
default_search_term=config.search.default_term,
|
||||
default_search_limit=config.search.default_limit,
|
||||
default_query=config.search.default_query,
|
||||
default_limit=config.search.default_limit,
|
||||
)
|
||||
|
||||
Running such container looks like this:
|
||||
|
|
|
@ -77,6 +77,8 @@ the application structure. It is **easy to understand and change** it.
|
|||
|
||||
Explore the documentation to know more about the ``Dependency Injector``.
|
||||
|
||||
.. _contents:
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
|
|
|
@ -126,6 +126,16 @@ using :doc:`Dependency Injector <../index>`:
|
|||
.. literalinclude:: ../../examples/miniapps/engines_cars/example_ioc_containers.py
|
||||
:language: python
|
||||
|
||||
What's next?
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Choose one of the following as a next step:
|
||||
|
||||
+ Pass the dependency injection :ref:`flask-tutorial`.
|
||||
+ Look at the other dependency injection :ref:`tutorials`.
|
||||
+ Know more about the :ref:`providers`.
|
||||
+ Go to the :ref:`contents`.
|
||||
|
||||
Useful links
|
||||
~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -7,6 +7,11 @@ that were made in every particular version.
|
|||
From version 0.7.6 *Dependency Injector* framework strictly
|
||||
follows `Semantic versioning`_
|
||||
|
||||
3.23.0
|
||||
------
|
||||
- Add ``Flask`` tutorial.
|
||||
- Add PyPI classifiers.
|
||||
|
||||
3.22.0
|
||||
------
|
||||
- Migrate docs to ``alabaster`` theme.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
.. _providers:
|
||||
|
||||
Providers
|
||||
=========
|
||||
|
||||
|
|
|
@ -2,3 +2,5 @@ Aiohttp tutorial
|
|||
================
|
||||
|
||||
Coming soon...
|
||||
|
||||
.. disqus::
|
||||
|
|
|
@ -2,3 +2,5 @@ Asyncio tutorial
|
|||
================
|
||||
|
||||
Coming soon...
|
||||
|
||||
.. disqus::
|
||||
|
|
File diff suppressed because it is too large
Load Diff
BIN
docs/tutorials/flask_images/screen_01.png
Normal file
BIN
docs/tutorials/flask_images/screen_01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
BIN
docs/tutorials/flask_images/screen_02.png
Normal file
BIN
docs/tutorials/flask_images/screen_02.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 647 KiB |
|
@ -1,3 +1,5 @@
|
|||
.. _tutorials:
|
||||
|
||||
Tutorials
|
||||
=========
|
||||
|
||||
|
@ -10,3 +12,5 @@ frameworks.
|
|||
flask
|
||||
aiohttp
|
||||
asyncio
|
||||
|
||||
.. disqus::
|
||||
|
|
|
@ -4,6 +4,8 @@ Flask Dependency Injection Example
|
|||
Application ``githubnavigator`` is a `Flask <https://flask.palletsprojects.com/>`_ +
|
||||
`Dependency Injector <http://python-dependency-injector.ets-labs.org/>`_ application.
|
||||
|
||||
.. image:: screenshot.png
|
||||
|
||||
Run
|
||||
---
|
||||
|
||||
|
@ -79,7 +81,7 @@ The output should be something like:
|
|||
.. code-block::
|
||||
|
||||
platform darwin -- Python 3.8.3, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
|
||||
plugins: flask-1.0.0, cov-2.10.0, asyncio-0.14.0
|
||||
plugins: flask-1.0.0, cov-2.10.0
|
||||
collected 2 items
|
||||
|
||||
githubnavigator/tests.py .. [100%]
|
||||
|
@ -88,10 +90,10 @@ The output should be something like:
|
|||
Name Stmts Miss Cover
|
||||
----------------------------------------------------
|
||||
githubnavigator/__init__.py 0 0 100%
|
||||
githubnavigator/application.py 8 0 100%
|
||||
githubnavigator/containers.py 11 0 100%
|
||||
githubnavigator/application.py 11 0 100%
|
||||
githubnavigator/containers.py 13 0 100%
|
||||
githubnavigator/services.py 14 0 100%
|
||||
githubnavigator/tests.py 33 0 100%
|
||||
githubnavigator/tests.py 32 0 100%
|
||||
githubnavigator/views.py 7 0 100%
|
||||
----------------------------------------------------
|
||||
TOTAL 73 0 100%
|
||||
TOTAL 77 0 100%
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
github:
|
||||
request_timeout: 10
|
||||
search:
|
||||
default_term: "Dependency Injector"
|
||||
default_limit: 5
|
||||
default_query: "Dependency Injector"
|
||||
default_limit: 10
|
||||
|
|
|
@ -32,6 +32,6 @@ class ApplicationContainer(containers.DeclarativeContainer):
|
|||
index_view = flask.View(
|
||||
views.index,
|
||||
search_service=search_service,
|
||||
default_search_term=config.search.default_term,
|
||||
default_search_limit=config.search.default_limit,
|
||||
default_query=config.search.default_query,
|
||||
default_limit=config.search.default_limit,
|
||||
)
|
||||
|
|
|
@ -11,9 +11,12 @@ class SearchService:
|
|||
def __init__(self, github_client: Github):
|
||||
self._github_client = github_client
|
||||
|
||||
def search_repositories(self, term, limit):
|
||||
def search_repositories(self, query, limit):
|
||||
"""Search for repositories and return formatted data."""
|
||||
repositories = self._github_client.search_repositories(term, **{'in': 'name'})
|
||||
repositories = self._github_client.search_repositories(
|
||||
query=query,
|
||||
**{'in': 'name'},
|
||||
)
|
||||
return [
|
||||
self._format_repo(repository)
|
||||
for repository in repositories[:limit]
|
||||
|
|
|
@ -7,24 +7,32 @@
|
|||
<h1 class="mb-4">Github Navigator</h1>
|
||||
|
||||
<form>
|
||||
<div class="form-group form-row">
|
||||
<label for="mySearch" class="col-form-label">Search for:</label>
|
||||
<div class="col-10">
|
||||
<input class="form-control" type="text" id="mySearch"
|
||||
placeholder="Type something to search on GitHub"
|
||||
name="search_term"
|
||||
value="{{ search_term if search_term }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<div class="col-10">
|
||||
<label for="search_query" class="col-form-label">
|
||||
Search for:
|
||||
</label>
|
||||
<input class="form-control" type="text" id="search_query"
|
||||
placeholder="Type something to search on the GitHub"
|
||||
name="query"
|
||||
value="{{ query if query }}">
|
||||
</div>
|
||||
<div class="col">
|
||||
<label for="search_limit" class="col-form-label">
|
||||
Limit:
|
||||
</label>
|
||||
<select class="form-control" id="search_limit" name="limit">
|
||||
{% for value in [5, 10, 20] %}
|
||||
<option {% if value == limit %}selected{% endif %}>
|
||||
{{ value }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% if repositories|length == 0 %}
|
||||
<small>No search results</small>
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
<small>Results found: {{ repositories|length }}</small>
|
||||
</p>
|
||||
<p><small>Results found: {{ repositories|length }}</small></p>
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
|
@ -32,22 +40,29 @@
|
|||
<th>#</th>
|
||||
<th>Repository</th>
|
||||
<th class="text-nowrap">Repository owner</th>
|
||||
<!-- <th class="text-nowrap">Created at</th>-->
|
||||
<th class="text-nowrap">Last commit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for repository in repositories %} {{n}}
|
||||
{% for repository in repositories %} {{n}}
|
||||
<tr>
|
||||
<th>{{ loop.index }}</th>
|
||||
<td><a href="{{ repository.url }}">{{ repository.name }}</a></td>
|
||||
<td><a href="{{ repository.owner.url }}"><img src="{{ repository.owner.avatar_url }}" alt="avatar" height="24" width="24"/></a>
|
||||
<a href="{{ repository.owner.url }}">{{ repository.owner.login }}</a>
|
||||
<td><a href="{{ repository.url }}">
|
||||
{{ repository.name }}</a>
|
||||
</td>
|
||||
<td><a href="{{ repository.owner.url }}">
|
||||
<img src="{{ repository.owner.avatar_url }}"
|
||||
alt="avatar" height="24" width="24"/></a>
|
||||
<a href="{{ repository.owner.url }}">
|
||||
{{ repository.owner.login }}</a>
|
||||
</td>
|
||||
<td><a href="{{ repository.latest_commit.url }}">
|
||||
{{ repository.latest_commit.sha }}</a>
|
||||
{{ repository.latest_commit.message }}
|
||||
{{ repository.latest_commit.author_name }}
|
||||
</td>
|
||||
<td><a href="{{ repository.latest_commit.url }}">{{ repository.latest_commit.sha }}</a> {{ repository.latest_commit['message'] }} {{ repository.latest_commit.author_name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -43,6 +43,7 @@ def test_index(client, app):
|
|||
response = client.get(url_for('index'))
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b'Results found: 2' in response.data
|
||||
|
||||
assert b'repo1-url' in response.data
|
||||
assert b'repo1-name' in response.data
|
||||
|
@ -65,4 +66,4 @@ def test_index_no_results(client, app):
|
|||
response = client.get(url_for('index'))
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b'No search results' in response.data
|
||||
assert b'Results found: 0' in response.data
|
||||
|
|
|
@ -5,15 +5,19 @@ from flask import request, render_template
|
|||
from .services import SearchService
|
||||
|
||||
|
||||
def index(search_service: SearchService, default_search_term, default_search_limit):
|
||||
search_term = request.args.get('search_term', default_search_term)
|
||||
limit = request.args.get('limit', default_search_limit, int)
|
||||
def index(
|
||||
search_service: SearchService,
|
||||
default_query: str,
|
||||
default_limit: int,
|
||||
):
|
||||
query = request.args.get('query', default_query)
|
||||
limit = request.args.get('limit', default_limit, int)
|
||||
|
||||
repositories = search_service.search_repositories(search_term, limit)
|
||||
repositories = search_service.search_repositories(query, limit)
|
||||
|
||||
return render_template(
|
||||
'index.html',
|
||||
search_term=search_term,
|
||||
query=query,
|
||||
limit=limit,
|
||||
repositories=repositories,
|
||||
)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
dependency-injector[flask,yaml]
|
||||
dependency-injector
|
||||
flask
|
||||
bootstrap-flask
|
||||
pygithub
|
||||
pyyaml
|
||||
pytest-flask
|
||||
pytest-cov
|
||||
|
|
BIN
examples/miniapps/ghnav-flask/screenshot.png
Normal file
BIN
examples/miniapps/ghnav-flask/screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 647 KiB |
8
setup.py
8
setup.py
|
@ -97,6 +97,14 @@ setup(name='dependency-injector',
|
|||
'Programming Language :: Python :: 3.8',
|
||||
'Programming Language :: Python :: Implementation :: CPython',
|
||||
'Programming Language :: Python :: Implementation :: PyPy',
|
||||
'Framework :: AsyncIO',
|
||||
'Framework :: Bottle',
|
||||
'Framework :: Django',
|
||||
'Framework :: Flask',
|
||||
'Framework :: Pylons',
|
||||
'Framework :: Pyramid',
|
||||
'Framework :: Pytest',
|
||||
'Framework :: TurboGears',
|
||||
'Topic :: Software Development',
|
||||
'Topic :: Software Development :: Libraries',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Dependency injector top-level package."""
|
||||
|
||||
__version__ = '3.22.0'
|
||||
__version__ = '3.23.0'
|
||||
"""Version number that follows semantic versioning.
|
||||
|
||||
:type: str
|
||||
|
|
Loading…
Reference in New Issue
Block a user