GithubHelp home page GithubHelp logo

package-url / packageurl-python Goto Github PK

View Code? Open in Web Editor NEW
60.0 60.0 41.0 14.18 MB

Python implementation of the package url spec. This project is sponsored by NLnet project https://nlnet.nl/project/vulnerabilitydatabase/ , the Google Summer of Code, nexB and other generous sponsors.

Python 97.66% Makefile 2.34%
hacktoberfest library package-url purl python

packageurl-python's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

packageurl-python's Issues

Bug in generic sourceforge purl generation in url2purl

I am getting an error when I run url2purl on some sourceforge URLs:

http://master.dl.sourceforge.net/project/googleimagedown/project/v1.1/GoogleImageDownloader-v1.1-src.tar.bz2

ValueError('too many values to unpack (expected 2)')

The problem is where we split on the substring "/project/" (https://github.com/package-url/packageurl-python/blob/main/src/packageurl/contrib/url2purl.py#L350) and we get more than 2 elements returned by the split.

Incorrect PURL inferred from download URL

With https://github.com/pypa/get-virtualenv/raw/20.0.31/public/virtualenv.pyz this purl is inferred:
pkg:github/pypa/get-virtualenv@raw#20.0.31/public/virtualenv.pyz and this is not correct.
It should be instead:
pkg:github/pypa/[email protected]#/public/virtualenv.pyz

>>> from packageurl import url2purl
>>> url2purl.get_purl('https://github.com/pypa/get-virtualenv/raw/20.0.31/public/virtualenv.pyz')
PackageURL(type='github', namespace='pypa', name='get-virtualenv', version='raw', qualifiers=OrderedDict(), subpath='20.0.31/public/virtualenv.pyz')

Consider using the stdlib to parse and build instead

The current code is working but rather contrived.... We can do better!
For instance with this snippet:

>>> try:
...     from urlparse import urlparse
... except ImportError:
...     # Python 3
...     from urllib.parse import urlparse
... 
>>> urlparse('GO:google.golang.org/genproto@abcdedf?arch=i386#/googleapis/api/annotations/', allow_fragments=True)
ParseResult(scheme='go', netloc='', path='google.golang.org/genproto@abcdedf', params='', query='arch=i386', fragment='/googleapis/api/annotations/')
>>> urlparse('npm:%40angular/[email protected]')
ParseResult(scheme='npm', netloc='', path='%40angular/[email protected]', params='', query='', fragment='')

@ashcrow ping :)

`setup.py` install is deprecated. Use build and pip and other standards-based tools

setuptools install is deprecated and a warning regarding this is displayed during this project's current build process:

> python setup.py build sdist bdist_wheel
...
running bdist_wheel
/Users/phorton/Documents/GitHub/madpah/packageurl-python/lib/python3.10/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
  warnings.warn(
...

I would suggest that this project adopts a more modern package manager such as Poetry.

@pombredanne - do you have thoughts on this?

Provide a Django model implementation of PURL

Probably in a new contrib/ module as a django_models.py:

from django.db import models


class PackageURLMixin(models.Model):
    """
    Abstract Model for Package URL "purl" fields support.
    """
    type = models.CharField(
        max_length=16,
        blank=True,
        null=True,
        help_text=_(
            'A short code to identify the type of this package. '
            'For example: gem for a Rubygem, docker for a container, '
            'pypi for a Python Wheel or Egg, maven for a Maven Jar, '
            'deb for a Debian package, etc.'
        )
    )

    namespace = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        help_text=_(
            'Package name prefix, such as Maven groupid, Docker image owner, '
            'GitHub user or organization, etc.'
        ),
    )

    name = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text=_('Name of the package.'),
    )

    version = models.CharField(
        max_length=50,
        blank=True,
        null=True,
        help_text=_('Version of the package.'),
    )

    qualifiers = models.CharField(
        max_length=1024,
        blank=True,
        null=True,
        help_text=_(
            'Extra qualifying data for a package such as the name of an OS, '
            'architecture, distro, etc.'
        ),
    )

    subpath = models.CharField(
        max_length=200,
        blank=True,
        null=True,
        help_text=_(
            'Extra subpath within a package, relative to the package root.'
        ),
    )

    class Meta:
        abstract = True

    @property
    def package_url(self):
        """
        Return a compact Package URL "purl" string.
        """
        try:
            purl = PackageURL(
                self.type, self.namespace, self.name,
                self.version, self.qualifiers, self.subpath
            )
        except ValueError:
            return ''
        return str(purl)

Signed-off-by: Thomas Druez [email protected]

Create generic purls for code.google.com archive URLs

https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/android-notifier/android-notifier-desktop-0.5.1-1.i386.rpm

would be

pkg:generic/code.google.com/android-notifier?download_url=https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/android-notifier/android-notifier-desktop-0.5.1-1.i386.rpm

where the type is generic, namespace is code.google.com, name is the project name, and the download url is set as a qualifier.

We do not use code.google.com as a type because code.google.com repos has been shut down.

PackageURL type is not hashable

Storing PackageURL instances in a set can be useful. Currently attempting this fails with the following error:

Python 3.8.2 (default, Feb 26 2020, 22:21:03) 
[GCC 9.2.1 20200130] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from packageurl import PackageURL
>>> {PackageURL(name='test', type='pypi')}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'collections.OrderedDict'

Improve GitHub support for url2purl

I've run the latest version of url2purl and I've noticed the following issues:
{'download_url': 'current_purl_that_looks_wrong'}

{
'https://bitbucket.org/multicoreware/x265/downloads/x265_2.6.tar.gz': 'pkg:bitbucket/multicoreware/x265@downloads#x265_2.6.tar.gz',
'https://bitbucket.org/robeden/trove/downloads/trove-3.0.3.zip': 'pkg:bitbucket/robeden/trove@downloads#trove-3.0.3.zip',

'https://github.com/FasterXML/woodstox/archive/woodstox-core-5.0.2.zip': 'pkg:github/fasterxml/[email protected]',
'https://github.com/adobe-fonts/source-code-pro/archive/2.030R-ro/1.050R-it.tar.gz': 'pkg:github/adobe-fonts/[email protected]/1.050R-it',
'https://github.com/cassandra-rb/simple_uuid/archive/simple_uuid-0.3.0.zip': 'pkg:github/cassandra-rb/simple_uuid@simple_uuid-0.3.0',
'https://github.com/djberg96/sys-filesystem/archive/sys-filesystem-1.1.4.zip': 'pkg:github/djberg96/[email protected]',
'https://github.com/freedesktop/xorg-intel-gpu-tools/archive/igt-gpu-tools-1.23.tar.gz': 'pkg:github/freedesktop/[email protected]',
'https://github.com/grnet/synnefo/archive/synnefo/v0.12.3.zip': 'pkg:github/grnet/synnefo@synnefo/v0.12.3',
'https://github.com/n8n-io/n8n/archive/[email protected]': 'pkg:github/n8n-io/n8n@n8n%400.23.0',
'https://github.com/nginx/nginx/archive/branches/stable-0.7.zip': 'pkg:github/nginx/nginx@branches/stable-0.7',

'https://github.com/fanf2/unifdef/blob/master/unifdef.c': 'pkg:github/fanf2/unifdef@blob#master/unifdef.c',
'https://github.com/joebeeson/amazon/blob/master/vendors/aws-sdk/sdk.class.php': 'pkg:github/joebeeson/amazon@blob#master/vendors/aws-sdk/sdk.class.php',
'https://github.com/modelfabric/yowl/blob/master/bin/yowl': 'pkg:github/modelfabric/yowl@blob#master/bin/yowl',

'https://github.com/downloads/mozilla/rhino/rhino1_7R4.zip': 'pkg:github/downloads/mozilla@rhino#rhino1_7R4.zip',

'https://github.com/pombredanne/schematics.git': 'pkg:github/pombredanne/schematics.git',
'https://github.com/syncthing/syncthing/releases/download/v0.14.36/syncthing-source-v0.14.36.tar.gz': 'pkg:github/syncthing/syncthing@releases#download/v0.14.36/syncthing-source-v0.14.36.tar.gz',
'https://github.com/torakiki/pdfsam/releases/download/v3.3.2/pdfsam-3.3.2-bin.zip': 'pkg:github/torakiki/pdfsam@releases#download/v3.3.2/pdfsam-3.3.2-bin.zip',
'https://github.com/yarnpkg/yarn/releases/download/v1.3.2/yarn-v1.3.2.tar.gz': 'pkg:github/yarnpkg/yarn@releases#download/v1.3.2/yarn-v1.3.2.tar.gz',
'https://github.com/z3APA3A/3proxy/releases/download/0.8.11/3proxy-0.8.11.zip': 'pkg:github/z3apa3a/3proxy@releases#download/0.8.11/3proxy-0.8.11.zip',

'https://raw.githubusercontent.com/LeZuse/flex-sdk/master/frameworks/projects/mx/src/mx/containers/accordionClasses/AccordionHeader.as': 'pkg:github/lezuse/flex-sdk/master/frameworks/projects/mx/src/mx/containers@accordionClasses#AccordionHeader.as',
'https://raw.githubusercontent.com/NCIP/lexevs/master/lgSharedLibraries/jettison/jettison-1.1.jar': 'pkg:github/ncip/lexevs/master/lgsharedlibraries@jettison#jettison-1.1.jar',
'https://raw.githubusercontent.com/jgallen23/routie/master/dist/routie.min.js': 'pkg:github/jgallen23/routie/master@dist#routie.min.js',
'https://raw.githubusercontent.com/jquery/jquery-ui/1.8.14/ui/jquery.ui.mouse.js': 'pkg:github/jquery/jquery-ui/1.8.14@ui#jquery.ui.mouse.js',
'https://raw.githubusercontent.com/mariopacio/projeto.dprf.info/master/assets/plugins/xbreadcrumbs/xbreadcrumbs.js': 'pkg:github/mariopacio/projeto.dprf.info/master/assets/plugins@xbreadcrumbs#xbreadcrumbs.js'
}

Increase name field size in packageurl.contrib.django.models.PackageURLMixin

I have a django webapp that uses packageurl.contrib.django.models.PackageURLMixin and I get the following error when I try to save a package with a very long name.

Traceback (most recent call last):
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.StringDataRightTruncation: value too long for type character varying(100)


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/core/management/__init__.py", line 413, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/core/management/base.py", line 354, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/core/management/base.py", line 398, in execute
    output = self.handle(*args, **options)
  File "/home/jono/nexb/src/dejacode/component_catalog/management/commands/setpurls.py", line 88, in handle
    Package.objects.filter(pk=package.pk).update(**package_url_dict)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/models/query.py", line 783, in update
    rows = query.get_compiler(self.db).execute_sql(CURSOR)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1559, in execute_sql
    cursor = super().execute_sql(result_type)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1175, in execute_sql
    cursor.execute(sql, params)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/backends/utils.py", line 98, in execute
    return super().execute(sql, params)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
django.db.utils.DataError: value too long for type character varying(100)

Python2 failure in src/packageurl/contrib/django/models.py

This isn't valid python2:

    normalized_purl = f'pkg:{purl}' if not purl.startswith('pkg:') else purl

Python2 doesn't support f-strings and I get an error when building the module:

byte-compiling build/bdist.linux-x86_64/egg/packageurl/contrib/django/models.py to models.pyc
  File "build/bdist.linux-x86_64/egg/packageurl/contrib/django/models.py", line 60
    normalized_purl = f'pkg:{purl}' if not purl.startswith('pkg:') else purl
                                  ^
SyntaxError: invalid syntax

suggestion purl2url.py: allow mirrors

In NixOS a special syntax is used in the package configurations that allow downloading from mirrors, which are then locally configured and can be changed or searched automatically, and allow a user to pick a mirror closest, or do some very basic failover.

An example is this package: https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/graphics/barcode/default.nix

    url = "mirror://gnu/${pname}/${pname}-${version}.tar.xz";

This then tells the download script to substitute the package and use the configured mirror. It might be useful for purl2url.py to either use something similar or to return something similar to what NixOS does, so the actual fetcher can then replace it with the correct mirror.

Adding type hints

hey ๐Ÿ˜„

Thanks for the great project ๐Ÿš€ We are using both your project and CycloneDX to create SBOMs.

I would like to know, if you are interested in adding type hints to your project? I'm a big supporter of improving Python projects by adding type hints to them and reduce the amount of errors, which come from passing the wrong types to a functions or expecting a different result to come back.

I'm willing to do the change, just need to know if you prefer stub files or inline type hints, I usually prefer the latter one? I would also add mypy to your CI to check, if the added type hints make sense or not ๐Ÿ™‚

Django model mixin too restrictive

We are using PackageURLMixin in nexB/vulnerablecode.

While trying to import security data from Debian, I've come across a version "number" that exceeds the limit of 50 characters on the version field of the model mixin: 1:0.0~git20170407.0.55a552f+REALLY.0.0~git20161012.0.5f31782-1.

Can we bump max_length to 255? Should I open a PR for it?

Use test suite from spec repo

This repo currently has a test suite file within the repo. As part of the test process it seems it would be better to grab the current one and test off that.

setting attributes of a packageurl object

Is it possible to set attributes (such as version) in a packageurl object?

>>> import packageurl
>>> purl = packageurl.PackageURL.from_string('pkg:generic/busybox')
>>> purl.version
>>> purl.version = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

Get URL from PURL

From gitter chat https://gitter.im/package-url/Lobby

@tclasen :

Anyone know why the python package isn't letting me get a url from a purl?
@app.command()
def get(purl: str):
    parsed = PackageURL.from_string(purl)
    typer.echo(f"Grabbing {parsed}")
    typer.echo("A", purl2url.get_url(purl))
    typer.echo("B", purl2url.get_url(parsed.to_string()))
    typer.echo("C", purl2url.get_url(str(parsed)))
    typer.echo("D", purl2url.get_url(parsed.to_string()))
For this I've tried the two following PURLs:

pkg:maven/org.apache.commons/[email protected]
pkg:pypi/[email protected]
And for both of them I successfully parse and can print the purl, but the A, B, C, D echos after that are all empty (but don't crash).

@pombredanne :

@tclasen because it has not been implemented yet : https://github.com/package-url/packageurl-python/blob/main/src/packageurl/contrib/purl2url.py :)
It should be reasonably straightforward using tidbits of code from https://github.com/nexB/fetchcode/blob/master/src/fetchcode/package.py and the expansive set in https://github.com/nexB/scancode-toolkit/tree/develop/src/packagedcode

Typing & PEP 561

Currently it seems the packageurl-python library is not typed according to PEP 561.

Raising for awareness.

FYI @jkowalleck

Use project name when creating a generic sourceforge purl in url2purl

When we create a generic sourceforge purl for sourceforge URLs that do not fit the pattern we use to parse sourceforge URLs, we should use the project name for the name field when creating the purl rather than using the filename.

For example, url2purl should process this:

http://master.dl.sourceforge.net/project/aloyscore/aloyscore/0.1a1%2520stable/0.1a1_stable_AloysCore.zip

into this:

pkg:sourceforge/aloyscore?download_url=http://master.dl.sourceforge.net/project/aloyscore/aloyscore/0.1a1%2520stable/0.1a1_stable_AloysCore.zip

instead of this:

pkg:sourceforge/0.1a1_stable_AloysCore.zip?download_url=http://master.dl.sourceforge.net/project/aloyscore/aloyscore/0.1a1%2520stable/0.1a1_stable_AloysCore.zip

Add convenience method to replace a purl component

The current implementation uses a namedtuple for PackageURL but this is an implementation detail that should be relied uppon. We should have a method to create a new purl from an existing purl passing new field values as arguments.

`purl_to_lookups` doesn't give dictionary for qualifiers

>>> purl = "pkg:alpine/openssl@0?arch=aarch64&distroversion=edge&reponame=main"
>>> purl_to_lookups(purl_str=purl)
{'type': 'alpine', 'name': 'openssl', 'version': '0', 'qualifiers': 'arch=aarch64&distroversion=edge&reponame=main'}

Consider handling googlesource.com URLs in url2purl

We should consider creating Package URLs for googlesource URLs. For example:

https://chromium.googlesource.com/v8/v8.git/%2Barchive/refs/heads/6.4.388.tar.gz

would be

pkg:googlesource/chromium/v8/[email protected]

Where googlesource is the type, chromium is the namespace, v8/v8 the name, and 6.4.388 the version.

Likewise:

https://android.googlesource.com/platform/system/bt.git/+archive/67f5f372.tar.gz

would be

pkg:googlesource/android/platform/system/bt@67f5f372

url2purl should not attempt to make a PackageURL from a URL without a path

I was running some code that updates purls based on download URLs and url2purl crashed on the URL http://apt-rpm.org/

Traceback (most recent call last):
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/packageurl/contrib/url2purl.py", line 54, in url2purl
    return purl_router.process(url)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/packageurl/contrib/route.py", line 174, in process
    endpoint = self.resolve(string)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/packageurl/contrib/route.py", line 197, in resolve
    raise NoRouteAvailable(string)
packageurl.contrib.route.NoRouteAvailable: http://apt-rpm.org/

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/core/management/__init__.py", line 413, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/core/management/base.py", line 354, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/django/core/management/base.py", line 398, in execute
    output = self.handle(*args, **options)
  File "/home/jono/nexb/src/dejacode/component_catalog/management/commands/setpurls.py", line 79, in handle
    package_url = url2purl.get_purl(package.download_url)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/packageurl/contrib/url2purl.py", line 58, in url2purl
    return build_generic_purl(url)
  File "/home/jono/nexb/src/dejacode/lib/python3.6/site-packages/packageurl/contrib/url2purl.py", line 105, in build_generic_purl
    file_name = uri_path_segments[-1]
IndexError: list index out of range

We should check after https://github.com/package-url/packageurl-python/blob/main/src/packageurl/contrib/url2purl.py#L104 to see if we have URL path segments before creating a purl.

Restore CI

travis.com is dead but still listed. We could enable GH actions and/or Azure in addition to appveyor

feature request: name to purl for rpm/deb

It would be very useful if it would be possible to supply a name of a package and then get a purl object.

For example. I would like to do something like:

>>> purl_object = packageurl.PackageURL.from_package_name('vim_8.1.0875-5_amd64.deb')

and get a correct purl object.

feature request: from_dict()

Currently there is a method to_dict() but there is no equivalent from_dict(). It might be useful to have this as well (use case: templating).

Simplify route declaration in url2purl

Following https://github.com/package-url/packageurl-python/pull/51/files/c1d41a8930b0b89dfc3774b4e18d89de5089e593..7877bb50102482468bdb9b32476d5a6151dc368e#r508692262

Working with regex syntax is always hard but should not be necessary for most of the simple routes.
For example, a common pattern '[^/]+' in path segment should be abstracted for better readability and new route addition.

We could re-use some ideas from the recent Django's URL route system that now replaces the old regex system: https://docs.djangoproject.com/en/3.1/topics/http/urls/#url-dispatcher

This system abstracts the regex complexity into "converters", for example r'^articles/(?P<year>[0-9]{4})/$' becomes articles/<yyyy:year>/

Using a current url2purl example:

  • pattern = r"https?://raw.githubusercontent.com/(?P<namespace>[^/]+)/(?P<name>[^/]+)/(?P<version>[^/]+)/(?P<subpath>.*)$"

Could become:

  • route = "https://raw.githubusercontent.com/<str:namespace>/<str:name>/<str:version>/<path:subpath>"

Much easier to write and to read.


Playing around with the Django's _route_to_regex

from django.urls.resolvers import _route_to_regex

route = "https://raw.githubusercontent.com/<str:namespace>/<str:name>/<str:version>/<path:subpath>"
pattern = _route_to_regex(route, is_endpoint=True)[0]
# -> "^https\\:\\/\\/raw\\.githubusercontent\\.com\\/(?P<namespace>[^/]+)\\/(?P<name>[^/]+)\\/(?P<version>[^/]+)\\/(?P<subpath>.+)$"

url = "https://raw.githubusercontent.com/LeZuse/flex-sdk/master/frameworks/projects/mx/src/mx/containers/accordionClasses/AccordionHeader.as"
re.compile(pattern, re.VERBOSE).match(url).groupdict()
# -> {'namespace': 'LeZuse', 'name': 'flex-sdk', 'version': 'master', 'subpath': 'frameworks/projects/mx/src/mx/containers/accordionClasses/AccordionHeader.as'}

We could add custom converter for the specific needs of purl https://docs.djangoproject.com/en/3.1/topics/http/urls/#registering-custom-path-converters
Some parts like the (http|https) will need support as well as the domain section is not part of the Django system:

from django.urls.resolvers import _route_to_regex
from django.urls.converters import register_converter
from django.urls.converters import StringConverter

class ProtocolConverter(StringConverter):
    regex = '(http|https|ftp)'

register_converter(ProtocolConverter, 'protocol')

route = "<protocol:protocol>://raw.githubusercontent.com/<str:namespace>/<str:name>/<str:version>/<path:subpath>"
_route_to_regex(route, is_endpoint=True)[0]

'^(?P<protocol>(http|https|ftp))\\:\\/\\/raw\\.githubusercontent\\.com\\/(?P<namespace>[^/]+)\\/(?P<name>[^/]+)\\/(?P<version>[^/]+)\\/(?P<subpath>.+)$'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.