open-source-ideas / ideas

💡 Looking for inspiration for your next open source project? Or perhaps you've got a brilliant idea you can't wait to share with others? Open Source Ideas is a community built specifically for this! 👋
6.52k stars 222 forks source link

Django URLconf type checker #292

Open spookylukey opened 2 years ago

spookylukey commented 2 years ago

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:

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

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)

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

Help/guidance

I'm happy to give help/suggestions for anyone interested but needing some pointers with any aspects.

AliSayyah commented 2 years ago

@spookylukey Hi there! This seems to be a great idea, and I want to help out. How do you recommend proceeding?

spookylukey commented 2 years ago

@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:

  1. 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.
  2. 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.
  3. 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
  4. 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
  5. 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.
  6. Install Sphinx and build the docs, then get them working on readthedocs.org
  7. 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:

KOLANICH commented 2 years ago

I wonder why not to generate them from function prototypes instead of checking?

AliSayyah commented 2 years ago

@spookylukey Thank you for your explanations🙏 I`ll keep you updated about the process.

AliSayyah commented 2 years ago

@KOLANICH Could you please explain more?

spookylukey commented 2 years ago

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.

KOLANICH commented 2 years ago
# 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
AliSayyah commented 2 years ago

I created the repository and required workflows. I would appreciate any feedback. https://github.com/AliSayyah/django-urlconf-checks

AliSayyah commented 2 years ago

@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?

spookylukey commented 2 years ago

Hey, this looks brilliant! 🎉️

I'll join that discussion.