From cce1549993bf9a6c0609a47e9458557fd4171c20 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Thu, 1 Oct 2020 18:01:10 -0400 Subject: [PATCH] Add rough django example --- examples/miniapps/django/README.rst | 117 +++++++++++++++++ examples/miniapps/django/db.sqlite3 | Bin 0 -> 131072 bytes .../django/githubnavigator/__init__.py | 9 ++ .../miniapps/django/githubnavigator/asgi.py | 16 +++ .../django/githubnavigator/containers.py | 22 ++++ .../django/githubnavigator/services.py | 44 +++++++ .../django/githubnavigator/settings.py | 121 ++++++++++++++++++ .../miniapps/django/githubnavigator/urls.py | 22 ++++ .../miniapps/django/githubnavigator/wsgi.py | 16 +++ examples/miniapps/django/manage.py | 21 +++ examples/miniapps/django/requirements.txt | 3 + examples/miniapps/django/web/__init__.py | 0 examples/miniapps/django/web/apps.py | 12 ++ .../miniapps/django/web/templates/index.html | 63 +++++++++ examples/miniapps/django/web/tests.py | 3 + examples/miniapps/django/web/urls.py | 7 + examples/miniapps/django/web/views.py | 31 +++++ 17 files changed, 507 insertions(+) create mode 100644 examples/miniapps/django/README.rst create mode 100644 examples/miniapps/django/db.sqlite3 create mode 100644 examples/miniapps/django/githubnavigator/__init__.py create mode 100644 examples/miniapps/django/githubnavigator/asgi.py create mode 100644 examples/miniapps/django/githubnavigator/containers.py create mode 100644 examples/miniapps/django/githubnavigator/services.py create mode 100644 examples/miniapps/django/githubnavigator/settings.py create mode 100644 examples/miniapps/django/githubnavigator/urls.py create mode 100644 examples/miniapps/django/githubnavigator/wsgi.py create mode 100755 examples/miniapps/django/manage.py create mode 100644 examples/miniapps/django/requirements.txt create mode 100644 examples/miniapps/django/web/__init__.py create mode 100644 examples/miniapps/django/web/apps.py create mode 100644 examples/miniapps/django/web/templates/index.html create mode 100644 examples/miniapps/django/web/tests.py create mode 100644 examples/miniapps/django/web/urls.py create mode 100644 examples/miniapps/django/web/views.py diff --git a/examples/miniapps/django/README.rst b/examples/miniapps/django/README.rst new file mode 100644 index 00000000..97ed23a9 --- /dev/null +++ b/examples/miniapps/django/README.rst @@ -0,0 +1,117 @@ +Dependency Injector + Sanic Example +===================================== + +Application ``githubnavigator`` is a `Django `_ + +`Dependency Injector `_ example application. + +Run +--- + +Create virtual environment: + +.. code-block:: bash + + virtualenv venv + . venv/bin/activate + +Install requirements: + +.. code-block:: bash + + pip install -r requirements.txt + +To run the application do: + +.. code-block:: bash + + export GIPHY_API_KEY=wBJ2wZG7SRqfrU9nPgPiWvORmloDyuL0 + python -m giphynavigator + +The output should be something like: + +.. code-block:: + + [2020-09-23 18:16:31 -0400] [48258] [INFO] Goin' Fast @ http://0.0.0.0:8000 + [2020-09-23 18:16:31 -0400] [48258] [INFO] Starting worker [48258] + +After that visit http://127.0.0.1:8000/ in your browser or use CLI command (``curl``, ``httpie``, +etc). You should see something like: + +.. code-block:: json + + { + "query": "Dependency Injector", + "limit": 10, + "gifs": [ + { + "url": "https://giphy.com/gifs/boxes-dependent-swbf2-6Eo7KzABxgJMY" + }, + { + "url": "https://giphy.com/gifs/depends-J56qCcOhk6hKE" + }, + { + "url": "https://giphy.com/gifs/web-series-ccstudios-bro-dependent-1lhU8KAVwmVVu" + }, + { + "url": "https://giphy.com/gifs/TheBoysTV-friends-friend-weneedeachother-XxR9qcIwcf5Jq404Sx" + }, + { + "url": "https://giphy.com/gifs/netflix-a-series-of-unfortunate-events-asoue-9rgeQXbwoK53pcxn7f" + }, + { + "url": "https://giphy.com/gifs/black-and-white-sad-skins-Hs4YzLs2zJuLu" + }, + { + "url": "https://giphy.com/gifs/always-there-for-you-i-am-here-PlayjhCco9jHBYrd9w" + }, + { + "url": "https://giphy.com/gifs/stream-famous-dollar-YT2dvOByEwXCdoYiA1" + }, + { + "url": "https://giphy.com/gifs/i-love-you-there-for-am-1BhGzgpZXYWwWMAGB1" + }, + { + "url": "https://giphy.com/gifs/life-like-twerk-9hlnWxjHqmH28" + } + ] + } + +.. note:: + + To create your own Giphy API key follow this + `guide `_. + +Test +---- + +This application comes with the unit tests. + +To run the tests do: + +.. code-block:: bash + + py.test giphynavigator/tests.py --cov=giphynavigator + +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: cov-2.10.0, sanic-1.6.1 + collected 3 items + + giphynavigator/tests.py ... [100%] + + ---------- coverage: platform darwin, python 3.8.3-final-0 ----------- + Name Stmts Miss Cover + --------------------------------------------------- + giphynavigator/__init__.py 0 0 100% + giphynavigator/__main__.py 4 4 0% + giphynavigator/application.py 12 0 100% + giphynavigator/containers.py 6 0 100% + giphynavigator/giphy.py 14 9 36% + giphynavigator/handlers.py 10 0 100% + giphynavigator/services.py 9 1 89% + giphynavigator/tests.py 34 0 100% + --------------------------------------------------- + TOTAL 89 14 84% diff --git a/examples/miniapps/django/db.sqlite3 b/examples/miniapps/django/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..70000be3c768bfd69f209cf6999d901d252b716b GIT binary patch literal 131072 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 +

Github Navigator

+ +
+
+
+ + +
+
+ + +
+
+
+ +

Results found: {{ repositories|length }}

+ + + + + + + + + + + + {% for repository in repositories %} {{n}} + + + + + + + {% endfor %} + +
#RepositoryRepository ownerLast commit
{{ loop.index }} + {{ repository.name }} + + avatar + + {{ repository.owner.login }} + + {{ repository.latest_commit.sha }} + {{ repository.latest_commit.message }} + {{ repository.latest_commit.author_name }} +
+ diff --git a/examples/miniapps/django/web/tests.py b/examples/miniapps/django/web/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/examples/miniapps/django/web/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/examples/miniapps/django/web/urls.py b/examples/miniapps/django/web/urls.py new file mode 100644 index 00000000..88a9caca --- /dev/null +++ b/examples/miniapps/django/web/urls.py @@ -0,0 +1,7 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path('', views.index, name='index'), +] diff --git a/examples/miniapps/django/web/views.py b/examples/miniapps/django/web/views.py new file mode 100644 index 00000000..97850b7b --- /dev/null +++ b/examples/miniapps/django/web/views.py @@ -0,0 +1,31 @@ +"""Views module.""" + +from django.http import HttpRequest, HttpResponse +from django.shortcuts import render +from dependency_injector.wiring import Provide + +from githubnavigator.containers import Container +from githubnavigator.services import SearchService + + +def index( + request: HttpRequest, + search_service: SearchService = Provide[Container.search_service], + default_query: str = Provide[Container.config.default.query], + default_limit: int = Provide[Container.config.default.limit.as_int()], +) -> HttpResponse: + query = request.GET.get('query', default_query) + limit = int(request.GET.get('limit', default_limit)) + + repositories = search_service.search_repositories(query, limit) + + return render( + request, + template_name='index.html', + context={ + 'query': query, + 'limit': limit, + 'limits': [5, 10, 20], + 'repositories': repositories, + } + )