Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable installing catchpy into an existing Django project #4

Open
wants to merge 43 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4671bac
ignore common virtual env names
d-flood Feb 20, 2024
a481aa5
`token` is already a string?
d-flood Feb 22, 2024
3034e2d
restructure under single main directory
d-flood Feb 22, 2024
0089a8e
Add python requirements as Dockerfilearg
d-flood Feb 22, 2024
3181902
refactor imports for new project structure
d-flood Feb 22, 2024
de19d59
convert legacy setup.py to pyproject.toml using hatch to build and pu…
d-flood Feb 22, 2024
7cfa947
divide urlpatterns so that a limited list can be imported in an exist…
d-flood Feb 22, 2024
07c2542
comment out failing annotatorjs test
d-flood Feb 22, 2024
9315702
handle when jwt is not prefixed with 'token'
d-flood Feb 22, 2024
58eecbd
bump
d-flood Feb 22, 2024
cf8fdd7
namespace the anno url endpoint
d-flood Feb 22, 2024
9b566d4
namespace urls to work the same standalone or in existing project
d-flood Feb 22, 2024
803efc2
rename Profile to CatchpyProfile
d-flood Feb 23, 2024
82168bb
update tests
d-flood Feb 23, 2024
7337a7a
update CatchpyProfile related name
d-flood Feb 23, 2024
87cbcaa
ensure that CatchpyProfile exists on the user
d-flood Feb 23, 2024
c0faff6
Add installation instructions for adding to existing Django project
d-flood Feb 23, 2024
9bc738c
fix rst anchor
d-flood Feb 23, 2024
79114aa
add packaging instructions
d-flood Feb 23, 2024
e323e04
update `docker-compose` to `docker compose`
d-flood Feb 23, 2024
04090b6
update python 3.12 subv
d-flood Feb 23, 2024
a1f443b
Update test.Dockerfile: use Python 3.12.2
d-flood Feb 24, 2024
483ffe3
pin dependencies
d-flood Feb 27, 2024
10288bf
remove instructions to add all deps to requirements file
d-flood Feb 27, 2024
0cb5b08
Merge branch 'django-package' of https://github.com/artshumrc/catchpy…
d-flood Feb 27, 2024
b5f6c67
bump version because deps now pinned
d-flood Feb 27, 2024
c246f35
rollback: "token" must be present
d-flood Mar 4, 2024
8cea46e
addmigration for Profile
d-flood Mar 4, 2024
720f406
Update requirements
ColeDCrawford May 28, 2024
8cd7d03
Update Python versions
ColeDCrawford May 28, 2024
42bdad4
Merge branch 'django-package' into update-requirements
ColeDCrawford May 29, 2024
2ed2b78
use newer `docker compose` instead of legacy `docker-compose` Python CLI
d-flood May 29, 2024
b0d9a19
Merge pull request #5 from artshumrc/update-requirements
d-flood May 29, 2024
88b9ba6
bump version and update deps versions in pyproject.toml
d-flood May 29, 2024
92a3d98
Remove pytz
ColeDCrawford May 30, 2024
69efe65
Update Python PATHs in test Dockerfile
ColeDCrawford May 30, 2024
faef987
Fix field reference in signal receiver
ColeDCrawford May 30, 2024
5db7fb5
Add ZoneInfo backport for Python3.8 support
ColeDCrawford May 30, 2024
4059d96
Merge pull request #6 from artshumrc/django-5
d-flood May 31, 2024
fda0dfe
Conditionally import ZoneInfo; use matrix strategy
ColeDCrawford Jun 3, 2024
6172c40
Update docs
ColeDCrawford Jun 3, 2024
43f3972
Update package version
ColeDCrawford Jun 5, 2024
b3e440d
Merge pull request #7 from artshumrc/django-5
ColeDCrawford Jun 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/workflows/ci-pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,25 @@ env:
jobs:
tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Build Docker images
run: |
docker compose -f docker-compose-test.yml build
PYTHON_VERSION=${{ matrix.python-version }} docker compose -f docker-compose-test.yml build

- name: Run Docker Compose containers
run: |
docker compose -f docker-compose-test.yml up -d
PYTHON_VERSION=${{ matrix.python-version }} docker compose -f docker-compose-test.yml up -d

- name: Run Pytest unit tests within Compose
run: |
docker compose -f docker-compose-test.yml exec web bash -c "tox"
docker compose -f docker-compose-test.yml exec web pytest

- name: Stop Docker Compose containers
if: always()
run: docker compose -f docker-compose.yml down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ __pycache__/
# Distribution / packaging
.Python
env/
.venv/
.env/
build/
develop-eggs/
dist/
Expand Down
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ RUN mkdir /code
WORKDIR /code
ADD . /code

RUN pip install -r catchpy/requirements/local.txt
ARG REQUIREMENTS_FILE=catchpy/requirements/local.txt

RUN pip install -r ${REQUIREMENTS_FILE}
121 changes: 111 additions & 10 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,22 @@ Quick Start

For those who want to quickly check out what catchpy does.

CatchPy can also be installed a a Django app in an existing Django project. See `below <#install-as-a-django-app>`_ for more details.

Make sure you have docker_ installed to try this quickstart.


::

# clone this repo
$> git clone https://github.com/nmaekawa/catchpy.git
$> cd catchpy

# start docker services
$> docker-compose up
$> docker-compose exec web python manage.py migrate
$> docker-compose exec web python manage.py createsuperuser
$> open http://localhost:8000/static/anno/index.html
$> docker compose up
$> docker compose exec web python manage.py migrate
$> docker compose exec web python manage.py createsuperuser
$> open http://localhost:9000/static/anno/index.html


This last command opens the API page, where you can try the `Web Annotation`_
Expand All @@ -47,14 +50,14 @@ To actually issue rest requests, you will need a jwt_ token. Generate one
like below::

# this generates a consumer/secret api key
$> docker-compose exec web python manage.py \
$> docker compose exec web python manage.py \
create_consumer_pair \
--consumer "my_consumer" \
--secret "super_secret" \
--expire_in_weeks 1

# this generates the token that expires in 10 min
$> docker-compose exec web python manage.py \
$> docker compose exec web python manage.py \
make_token \
--user "exceptional_user" \
--api_key "my_consumer" \
Expand Down Expand Up @@ -159,10 +162,10 @@ tests are located under each Django app:
Github Actions CI
---------------
Github Actions is configured to run unit tests on every new PR. The tests are configured in
``.github/workflows/ci-pytest.yml``. The workflow is configured to run tests on Python3.8-3.12 using
``tox``.

---eop
``.github/workflows/ci-pytest.yml``. The workflow is configured to run tests on Python 3.8-3.12
(currently supported versions) using `pytest` and a parallelized Github Actions matrix strategy which passes
the Python version as a build argument to the Dockerfile. `tox` is configured for local developmment
tests if that is preferred over `act`.


.. _W3C Web Annotation Data Model: https://www.w3.org/TR/annotation-model/
Expand All @@ -173,5 +176,103 @@ Github Actions is configured to run unit tests on every new PR. The tests are co
.. _jwt: https://jwt.io


Install as a Django app
-----------------------

Add to your `requirements.txt`:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to set these up directly as requirements, so that if you add the CatchPy package it will install these?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call; in fact, this is already the case but the package dependencies aren't pinned.


.. code-block:: text

# Include the latest release from this repository
https://github.com/artshumrc/catchpy/releases/download/v2.7.1-django-package/catchpy-2.7.0.tar.gz

Add to your `INSTALLED_APPS` in your Django settings:

.. code-block:: python

INSTALLED_APPS = [
...
'catchpy.anno',
'catchpy.consumer',
...
]

Add to your middleware in your Django settings:

.. code-block:: python

MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'catchpy.middleware.HxCommonMiddleware',
'catchpy.consumer.jwt_middleware.jwt_middleware',
...
]

Add the following to your Django settings:

.. code-block:: python

# catchpy settings
CATCH_JSONLD_CONTEXT_IRI = os.environ.get(
'CATCH_JSONLD_CONTEXT_IRI',
'http://catchpy.harvardx.harvard.edu.s3.amazonaws.com/jsonld/catch_context_jsonld.json')

# max number of rows to be returned in a search request
CATCH_RESPONSE_LIMIT = int(os.environ.get('CATCH_RESPONSE_LIMIT', 200))

# default platform for annotatorjs annotations
CATCH_DEFAULT_PLATFORM_NAME = os.environ.get(
'CATCH_DEFAULT_PLATFORM_NAME', 'hxat-edx_v1.0')

# admin id overrides all permissions, when requesting_user
CATCH_ADMIN_GROUP_ID = os.environ.get('CATCH_ADMIN_GROUP_ID', '__admin__')

# log request time
CATCH_LOG_REQUEST_TIME = os.environ.get(
'CATCH_LOG_REQUEST_TIME', 'false').lower() == 'true'
CATCH_LOG_SEARCH_TIME = os.environ.get(
'CATCH_LOG_SEARCH_TIME', 'false').lower() == 'true'

# log jwt and jwt error message
CATCH_LOG_JWT = os.environ.get(
'CATCH_LOG_JWT', 'false').lower() == 'true'
CATCH_LOG_JWT_ERROR = os.environ.get(
'CATCH_LOG_JWT_ERROR', 'false').lower() == 'true'

# annotation body regexp for sanity checks
CATCH_ANNO_SANITIZE_REGEXPS = [
re.compile(r) for r in ['<\s*script', ]
]

#
# settings for django-cors-headers
#
CORS_ORIGIN_ALLOW_ALL = True # accept requests from anyone
CORS_ALLOW_HEADERS = default_headers + (
'x-annotator-auth-token', # for back-compat
)

Add to your Django urls:

.. code-block:: python

from django.urls import path, include

from catchpy.urls import urls as catchpy_urls

urlpatterns = [
...
path("catchpy/", include(catchpy_urls)),
...
]

Finally, be sure to run migrations.

Build and Package
-----------------

- install `hatch <https://hatch.pypa.io/latest/install/>`_
- set version in ``catchpy/__init__.py``
- package (create Python wheel) ``hatch build``
- publish to PYPI with ``hatch publish``
5 changes: 0 additions & 5 deletions anno/apps.py

This file was deleted.

2 changes: 1 addition & 1 deletion catchpy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# important to use single quotes in version string
# for post-commit tagging
__version__ = '2.6.0' # transfer_instructor endpoint
__version__ = '2.9.1'
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import sys
from django.core.management import BaseCommand

from anno.crud import CRUD
from anno.json_models import Catcha
from catchpy.anno.crud import CRUD
from catchpy.anno.json_models import Catcha


class Command(BaseCommand):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json

from anno.crud import CRUD
from catchpy.anno.crud import CRUD
from django.core.management import BaseCommand


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import sys
from django.core.management import BaseCommand

from anno.crud import CRUD
from catchpy.anno.crud import CRUD


class Command(BaseCommand):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import sys
from django.core.management import BaseCommand

from anno.anno_defaults import CATCH_ANNO_FORMAT
from anno.anno_defaults import CATCH_DEFAULT_PLATFORM_NAME
from anno.crud import CRUD
from anno.views import _format_response
from catchpy.anno.anno_defaults import CATCH_ANNO_FORMAT
from catchpy.anno.anno_defaults import CATCH_DEFAULT_PLATFORM_NAME
from catchpy.anno.crud import CRUD
from catchpy.anno.views import _format_response


class Command(BaseCommand):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json

from anno.crud import CRUD
from catchpy.anno.crud import CRUD
from django.core.management import BaseCommand


Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json

from anno.crud import CRUD
from catchpy.anno.crud import CRUD
from django.core.management import BaseCommand


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json

import dateutil
from anno.crud import CRUD
from catchpy.anno.crud import CRUD
from django.core.management import BaseCommand


Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading