ideas
ideas copied to clipboard
Django URLconf type checker
Project description
Given some URLs configured like this (as per the Django docs):
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
And some views like this:
# views.py
def special_case(request):
pass
def year_archive(request, year: int):
pass
def month_archive(request, year: int, month: int):
pass
def article_detail(request, year: int, month: int, slug: str):
pass
...we can check that the types of parameters match. So, for example, if we changed one of these but forget to change the other, we'd be immediately be notified, instead of waiting for runtime errors or test failures.
The good thing about this - I've already written a big chunk of the code! You can find it here: https://github.com/spookylukey/django-views-the-right-way/blob/master/code/the_right_way/url_checker.py . I've started using this code in some real projects, but it needs work, and I think it could be useful to a lot of people in the Django community.
What is missing is:
- tests
- docs
- packaging - i.e. making a nice, easy to install and use package out of this.
- cleaning up the code
- missing features mentioned in the code
Relevant Technology
You need experience with Django and Python. Very advanced knowledge is not needed, but it will introduce you to introspection and type annotations if you don't have that knowledge already. The main skills used/developed will be to do with testing, documentation and package management.
Complexity and required time
Complexity
- [ ] Beginner - This project requires no or little prior knowledge of the technologies specified to contribute to the project
- [x] Intermediate - The user should have some prior knowledge of the technologies to the point where they know how to use it, but not necessarily all the nooks and crannies of the technology
- [ ] Advanced - The project requires the user to have a good understanding of all components of the project to contribute
This is easily small enough to be managed by a single person, and will get your feet wet with running a small project.
Required time (ETA)
- [ ] Little work - A couple of days
- [x] Medium work - A week or two
- [ ] Much work - The project will take more than a couple of weeks and serious planning is required
The bare minimum to get this project packaged could be done in a couple of days, but I think the project could benefit from tests, docs etc. which would take longer.
Categories
- [ ] Mobile app
- [ ] IoT
- [ ] Web app
- [ ] Frontend/UI
- [ ] AI/ML
- [ ] APIs/Backend
- [ ] Voice Assistant
- [x] Developer Tooling
- [ ] Extension/Plugin/Add-On
- [ ] Design/UX
- [ ] AR/VR
- [ ] Bots
- [ ] Security
- [ ] Blockchain
- [ ] Futuristic Tech/Something Unique
Help/guidance
I'm happy to give help/suggestions for anyone interested but needing some pointers with any aspects.
@spookylukey Hi there! This seems to be a great idea, and I want to help out. How do you recommend proceeding?
@AliSayyah Thanks for your interest!
I'm assuming you already know some Python and Django - if not, this project might not be for you.
This is how I would go about it:
- Copy the code I linked above, and see if you can get it working in the context of Django project - this won't be the final home, just an initial test so that you can see the pieces.
- Start a new repo and project for the code. You might want to use cookie-cutter to get you started. Since this will be a library that uses Django, rather than a Django application, I'd recommend using a Python library template, not the "Cookiecutter Django" template which is for a Django project.
- Add the code, and start writing some tests. You need to pick a test framework - probably pytest and pytest-django would be best, but you can also use the normal unittest style that is in the Django docs. At this point, I wouldn't try to write all the possible tests, a few will do. The hardest will be working out how to write them, especially since this library is a bit unusual - all it does is emit "checks" at development time, rather than do anything at runtime. Look at existing projects that use Django checks and see how they write tests. Maybe Django itself - see https://github.com/django/django/blob/main/tests/check_framework/test_urls.py
- Try to get a package published on PyPI - it will be a 0.0.1 version at this point, that's fine, you are going to be the only one who uses it. You'll need the Python Packaging User Guide
- Install the package in some other Django project and try to use it. At this point you will write the installation docs, and possibly discover that it doesn't work, or you messed up the packaging etc.
- Install Sphinx and build the docs, then get them working on readthedocs.org
- Iterate on the above - code, tests, docs, packaging - until you have something ready for the world to see.
A quick look at your GitHub contributions makes me think you will not be lost with all of the above, but some of these steps could be hard if you've never done them before. I'm happy to try and help if you get stuck.
In addition: the following are not necessary, especially if you are overwhelmed by all this, but at some point I would highly recommend:
- set up CI - I would recommend GitHub Actions rather than Travis (the template above uses TravisCI). There are quite a few Python packages you can copy workflows from e.g. django-money. Also the zllionare/cookiecutter-pypackage/ is another template you can copy workflows from (see .github/workflows).
- use black, isort, flake8
- set up pre-commit in your repo, which can run the above tools for you when you commit
I wonder why not to generate them from function prototypes instead of checking?
@spookylukey Thank you for your explanations🙏 I`ll keep you updated about the process.
@KOLANICH Could you please explain more?
I wonder why not to generate them from function prototypes instead of checking?
That wouldn't solve the problem of them getting out of sync. In other frameworks, URLs and view functions are closer together, like in Flask, but in Django they are separated.
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/{}/', views.year_archive),
path('articles/{}/{}/', views.month_archive),
path('articles/{}/{}/{}/', views.article_detail),
# or
path('articles/{slash_delimited}', views.article_detail), #magic name
]
# views.py
def special_case(request):
pass
def year_archive(request, year: int):
pass
def month_archive(request, year: int, month: int):
pass
def article_detail(request, year: int, month: int, slug: slug):
pass
I created the repository and required workflows. I would appreciate any feedback. https://github.com/AliSayyah/django-urlconf-checks
@spookylukey hey! https://pypi.org/project/django-urlconfchecks/ the package is now functional. I'll start working on better tests and TODOs. Thank you for your assistance. https://github.com/AliSayyah/django-urlconfchecks/discussions/23 Can you please join me in this discussion?
Hey, this looks brilliant! 🎉️
I'll join that discussion.