mirror of
https://github.com/task-17-lct/backend.git
synced 2024-11-27 18:43:44 +03:00
init
This commit is contained in:
parent
63d4a0a850
commit
4f5e597258
|
@ -1,2 +1,10 @@
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
from passfinder.recomendations.api.views import TinderView
|
||||||
|
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
|
||||||
|
router.register('tinder', TinderView)
|
||||||
|
|
||||||
app_name = "api"
|
app_name = "api"
|
||||||
urlpatterns = []
|
urlpatterns = router.urls
|
|
@ -39,7 +39,7 @@
|
||||||
# DATABASES
|
# DATABASES
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#databases
|
# https://docs.djangoproject.com/en/dev/ref/settings/#databases
|
||||||
DATABASES = {"default": env.db("DATABASE_URL")}
|
DATABASES = {"default": env.db("DATABASE_URL", "postgres://postgres:Ilvas2006@localhost:5432/passfinder")}
|
||||||
DATABASES["default"]["ATOMIC_REQUESTS"] = True
|
DATABASES["default"]["ATOMIC_REQUESTS"] = True
|
||||||
# https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-DEFAULT_AUTO_FIELD
|
# https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-DEFAULT_AUTO_FIELD
|
||||||
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||||
|
@ -77,6 +77,7 @@
|
||||||
LOCAL_APPS = [
|
LOCAL_APPS = [
|
||||||
"passfinder.users",
|
"passfinder.users",
|
||||||
"passfinder.events",
|
"passfinder.events",
|
||||||
|
"passfinder.recomendations"
|
||||||
]
|
]
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
|
# https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
|
||||||
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
|
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
|
||||||
|
@ -284,9 +285,9 @@
|
||||||
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-timezone
|
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-timezone
|
||||||
CELERY_TIMEZONE = TIME_ZONE
|
CELERY_TIMEZONE = TIME_ZONE
|
||||||
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-broker_url
|
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-broker_url
|
||||||
CELERY_BROKER_URL = env("CELERY_BROKER_URL")
|
#CELERY_BROKER_URL = env("CELERY_BROKER_URL")
|
||||||
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-result_backend
|
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-result_backend
|
||||||
CELERY_RESULT_BACKEND = CELERY_BROKER_URL
|
#CELERY_RESULT_BACKEND = CELERY_BROKER_URL
|
||||||
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#result-extended
|
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#result-extended
|
||||||
CELERY_RESULT_EXTENDED = True
|
CELERY_RESULT_EXTENDED = True
|
||||||
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#result-backend-always-retry
|
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#result-backend-always-retry
|
||||||
|
|
|
@ -43,11 +43,11 @@
|
||||||
}
|
}
|
||||||
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips
|
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips
|
||||||
INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"]
|
INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"]
|
||||||
if env("USE_DOCKER") == "yes":
|
# if env("USE_DOCKER") == "yes":
|
||||||
import socket
|
# import socket
|
||||||
|
|
||||||
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
|
# hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
|
||||||
INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
|
# INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
|
||||||
|
|
||||||
# django-extensions
|
# django-extensions
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from passfinder.events.models import Hotel, HotelPhone, City
|
from passfinder.events.models import Hotel, HotelPhone, City, Event
|
||||||
|
|
||||||
|
|
||||||
class HotelPhoneSerializer(serializers.ModelSerializer):
|
class HotelPhoneSerializer(serializers.ModelSerializer):
|
||||||
|
@ -29,3 +29,9 @@ class MuseumSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Hotel
|
model = Hotel
|
||||||
exclude = "oid"
|
exclude = "oid"
|
||||||
|
|
||||||
|
|
||||||
|
class EventSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Event
|
||||||
|
fields = ('type', 'title', 'description', 'city', 'oid')
|
0
passfinder/recomendations/__init__.py
Normal file
0
passfinder/recomendations/__init__.py
Normal file
3
passfinder/recomendations/admin.py
Normal file
3
passfinder/recomendations/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
7
passfinder/recomendations/api/serializers.py
Normal file
7
passfinder/recomendations/api/serializers.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
from passfinder.events.api.serializers import EventSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class TinderProceedSerializer(serializers.Serializer):
|
||||||
|
action = serializers.ChoiceField(['left', 'right'], write_only=True)
|
||||||
|
event = EventSerializer(read_only=True)
|
26
passfinder/recomendations/api/views.py
Normal file
26
passfinder/recomendations/api/views.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
from typing import Any
|
||||||
|
from rest_framework import viewsets, mixins
|
||||||
|
from rest_framework.request import Request
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from passfinder.events.models import Event
|
||||||
|
from passfinder.events.api.serializers import EventSerializer
|
||||||
|
from random import choice
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from .serializers import TinderProceedSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class TinderView(viewsets.GenericViewSet):
|
||||||
|
serializer_class = EventSerializer
|
||||||
|
model = Event
|
||||||
|
queryset = Event.objects.all()
|
||||||
|
|
||||||
|
@action(methods=['GET'], detail=False, serializer_class=EventSerializer)
|
||||||
|
def start(self, request: Request, *args: Any, **kwargs: Any):
|
||||||
|
event = EventSerializer(choice(Event.objects.all()))
|
||||||
|
return Response(data=event.data, status=200)
|
||||||
|
|
||||||
|
@action(methods=['POST'], detail=True, serializer_class=TinderProceedSerializer)
|
||||||
|
def proceed(self, request: Request, *args: Any, **kwargs: Any):
|
||||||
|
event = EventSerializer(choice(Event.objects.all()))
|
||||||
|
return Response(data={'event': event.data}, status=200)
|
6
passfinder/recomendations/apps.py
Normal file
6
passfinder/recomendations/apps.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class RecomendationsConfig(AppConfig):
|
||||||
|
default_auto_field = "django.db.models.BigAutoField"
|
||||||
|
name = "passfinder.recomendations"
|
75
passfinder/recomendations/migrations/0001_initial.py
Normal file
75
passfinder/recomendations/migrations/0001_initial.py
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# Generated by Django 4.2.1 on 2023-05-21 10:36
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("events", "0011_remove_event_purchase_method_and_more"),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="UserPreferences",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"preferred_concerts",
|
||||||
|
models.ManyToManyField(
|
||||||
|
related_name="preffered_users_concert", to="events.event"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"preffered_movies",
|
||||||
|
models.ManyToManyField(
|
||||||
|
related_name="preffered_user_movie", to="events.event"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"preffered_plays",
|
||||||
|
models.ManyToManyField(
|
||||||
|
related_name="preffered_user_play", to="events.event"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unpreferred_concerts",
|
||||||
|
models.ManyToManyField(
|
||||||
|
related_name="unpreffered_users_concert", to="events.event"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unpreffered_lays",
|
||||||
|
models.ManyToManyField(
|
||||||
|
related_name="unpreffered_users_play", to="events.event"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"unpreffered_movies",
|
||||||
|
models.ManyToManyField(
|
||||||
|
related_name="unpreffered_user_movie", to="events.event"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
0
passfinder/recomendations/migrations/__init__.py
Normal file
0
passfinder/recomendations/migrations/__init__.py
Normal file
16
passfinder/recomendations/models.py
Normal file
16
passfinder/recomendations/models.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
from django.db import models
|
||||||
|
from passfinder.users.models import User
|
||||||
|
from passfinder.events.models import Event
|
||||||
|
|
||||||
|
|
||||||
|
class UserPreferences(models.Model):
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
preffered_plays = models.ManyToManyField(Event, related_name='preffered_user_play')
|
||||||
|
unpreffered_lays = models.ManyToManyField(Event, related_name='unpreffered_users_play')
|
||||||
|
|
||||||
|
preffered_movies = models.ManyToManyField(Event, related_name='preffered_user_movie')
|
||||||
|
unpreffered_movies = models.ManyToManyField(Event, related_name='unpreffered_user_movie')
|
||||||
|
|
||||||
|
preferred_concerts = models.ManyToManyField(Event, related_name='preffered_users_concert')
|
||||||
|
unpreferred_concerts = models.ManyToManyField(Event, related_name='unpreffered_users_concert')
|
BIN
passfinder/recomendations/service/mapping/attractions.pickle
Normal file
BIN
passfinder/recomendations/service/mapping/attractions.pickle
Normal file
Binary file not shown.
BIN
passfinder/recomendations/service/mapping/concerts.pickle
Normal file
BIN
passfinder/recomendations/service/mapping/concerts.pickle
Normal file
Binary file not shown.
BIN
passfinder/recomendations/service/mapping/excursii.pickle
Normal file
BIN
passfinder/recomendations/service/mapping/excursii.pickle
Normal file
Binary file not shown.
BIN
passfinder/recomendations/service/mapping/kino.pickle
Normal file
BIN
passfinder/recomendations/service/mapping/kino.pickle
Normal file
Binary file not shown.
26
passfinder/recomendations/service/mapping/mapping.py
Normal file
26
passfinder/recomendations/service/mapping/mapping.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
attraction_mapping = None
|
||||||
|
cinema_mapping = None
|
||||||
|
plays_mapping = None
|
||||||
|
excursion_mapping = None
|
||||||
|
concert_mapping = None
|
||||||
|
|
||||||
|
with open('passfinder/recomendations/service/mapping/attractions.pickle', 'rb') as file:
|
||||||
|
attraction_mapping = pickle.load(file)
|
||||||
|
|
||||||
|
|
||||||
|
with open('passfinder/recomendations/service/mapping/kino.pickle', 'rb') as file:
|
||||||
|
cinema_mapping = pickle.load(file)
|
||||||
|
|
||||||
|
|
||||||
|
with open('passfinder/recomendations/service/mapping/spektakli.pickle', 'rb') as file:
|
||||||
|
plays_mapping = pickle.load(file)
|
||||||
|
|
||||||
|
|
||||||
|
with open('passfinder/recomendations/service/mapping/excursii.pickle', 'rb') as file:
|
||||||
|
excursion_mapping = pickle.load(file)
|
||||||
|
|
||||||
|
|
||||||
|
with open('passfinder/recomendations/service/mapping/concerts.pickle', 'rb') as file:
|
||||||
|
concert_mapping = pickle.load(file)
|
BIN
passfinder/recomendations/service/mapping/spektakli.pickle
Normal file
BIN
passfinder/recomendations/service/mapping/spektakli.pickle
Normal file
Binary file not shown.
BIN
passfinder/recomendations/service/models/concerts.ann
Normal file
BIN
passfinder/recomendations/service/models/concerts.ann
Normal file
Binary file not shown.
BIN
passfinder/recomendations/service/models/dost.ann
Normal file
BIN
passfinder/recomendations/service/models/dost.ann
Normal file
Binary file not shown.
BIN
passfinder/recomendations/service/models/excursii.ann
Normal file
BIN
passfinder/recomendations/service/models/excursii.ann
Normal file
Binary file not shown.
BIN
passfinder/recomendations/service/models/kino.ann
Normal file
BIN
passfinder/recomendations/service/models/kino.ann
Normal file
Binary file not shown.
22
passfinder/recomendations/service/models/models.py
Normal file
22
passfinder/recomendations/service/models/models.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
from annoy import AnnoyIndex
|
||||||
|
|
||||||
|
N_DIMENSIONAL = 768
|
||||||
|
|
||||||
|
attracion_model = AnnoyIndex(N_DIMENSIONAL, 'angular')
|
||||||
|
attracion_model.load('passfinder/recomendations/service/models/dost.ann')
|
||||||
|
|
||||||
|
|
||||||
|
cinema_model = AnnoyIndex(N_DIMENSIONAL, 'angular')
|
||||||
|
cinema_model.load('passfinder/recomendations/service/models/kino.ann')
|
||||||
|
|
||||||
|
|
||||||
|
plays_model = AnnoyIndex(N_DIMENSIONAL, 'angular')
|
||||||
|
plays_model.load('passfinder/recomendations/service/models/spektatli.ann')
|
||||||
|
|
||||||
|
|
||||||
|
excursion_model = AnnoyIndex(N_DIMENSIONAL, 'angular')
|
||||||
|
excursion_model.load('passfinder/recomendations/service/models/excursii.ann')
|
||||||
|
|
||||||
|
|
||||||
|
concert_model = AnnoyIndex(N_DIMENSIONAL, 'angular')
|
||||||
|
concert_model.load('passfinder/recomendations/service/models/concerts.ann')
|
BIN
passfinder/recomendations/service/models/spektatli.ann
Normal file
BIN
passfinder/recomendations/service/models/spektatli.ann
Normal file
Binary file not shown.
39
passfinder/recomendations/service/service.py
Normal file
39
passfinder/recomendations/service/service.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
from annoy import AnnoyIndex
|
||||||
|
from .mapping.mapping import *
|
||||||
|
from .models.models import *
|
||||||
|
from passfinder.events.models import Event
|
||||||
|
|
||||||
|
|
||||||
|
def get_nearest_(instance_model, model_type, mapping, nearest_n, ml_model):
|
||||||
|
how_many = len(Event.objects.filter(type=model_type))
|
||||||
|
|
||||||
|
index = mapping.index(instance_model.oid)
|
||||||
|
nearest = ml_model.get_nns_by_item(index, len(mapping))
|
||||||
|
|
||||||
|
res = []
|
||||||
|
for i in range(how_many):
|
||||||
|
try:
|
||||||
|
res.append(Event.objects.get(oid=mapping[nearest[i]]))
|
||||||
|
except Event.DoesNotExist: ...
|
||||||
|
if len(res) == nearest_n: break
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def nearest_attraction(attraction, nearest_n):
|
||||||
|
return get_nearest_(attraction, 'attraction', attraction_mapping, nearest_n, attracion_model)
|
||||||
|
|
||||||
|
|
||||||
|
def nearest_movie(movie, nearest_n):
|
||||||
|
return get_nearest_(movie, 'movie', cinema_mapping, nearest_n, cinema_model)
|
||||||
|
|
||||||
|
|
||||||
|
def nearest_plays(play, nearest_n):
|
||||||
|
return get_nearest_(play, 'play', plays_mapping, nearest_n, plays_model)
|
||||||
|
|
||||||
|
|
||||||
|
def nearest_excursion(excursion, nearest_n):
|
||||||
|
return get_nearest_(excursion, 'excursion', excursion_mapping, nearest_n, excursion_model)
|
||||||
|
|
||||||
|
|
||||||
|
def nearest_concert(concert, nearest_n):
|
||||||
|
return get_nearest_(concert, 'concert', concert_mapping, nearest_n, concert_model)
|
3
passfinder/recomendations/tests.py
Normal file
3
passfinder/recomendations/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
3
passfinder/recomendations/views.py
Normal file
3
passfinder/recomendations/views.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
|
@ -3,7 +3,7 @@
|
||||||
from django.db.models.enums import ChoicesMeta
|
from django.db.models.enums import ChoicesMeta
|
||||||
|
|
||||||
|
|
||||||
def count_max_length(choices: Iterable | ChoicesMeta):
|
def count_max_length(choices: any):
|
||||||
if isinstance(choices, ChoicesMeta):
|
if isinstance(choices, ChoicesMeta):
|
||||||
return max([len(val) for val in choices.values])
|
return max([len(val) for val in choices.values])
|
||||||
return max([len(val) for val, _ in choices])
|
return max([len(val) for val, _ in choices])
|
||||||
|
|
2
poetry.lock
generated
2
poetry.lock
generated
|
@ -2805,5 +2805,5 @@ files = [
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.11"
|
python-versions = "^3.8"
|
||||||
content-hash = "f28dac962f7703c39a58bd0f7640a1cc37af3dccd44f124e57e71d19d85278c0"
|
content-hash = "f28dac962f7703c39a58bd0f7640a1cc37af3dccd44f124e57e71d19d85278c0"
|
||||||
|
|
|
@ -6,7 +6,7 @@ authors = ["Alexandr Karpov <alexandr.d.karpov@gmail.com>"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.11"
|
python = "^3.8"
|
||||||
psycopg2 = "^2.9.5"
|
psycopg2 = "^2.9.5"
|
||||||
pytz = "^2022.7"
|
pytz = "^2022.7"
|
||||||
psutil = "^5.9.4"
|
psutil = "^5.9.4"
|
||||||
|
|
134
requirements.txt
Normal file
134
requirements.txt
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
amqp==5.1.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
anyio==3.6.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
appnope==0.1.3 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "darwin"
|
||||||
|
argon2-cffi-bindings==21.2.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
argon2-cffi==21.3.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
asgiref==3.6.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
astroid==2.15.5 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
asttokens==2.2.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
async-timeout==4.0.2 ; python_version >= "3.9" and python_full_version <= "3.9"
|
||||||
|
attrs==23.1.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
backcall==0.2.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
billiard==3.6.4.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
black==22.12.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
celery==5.2.7 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
celery[redis]==5.2.7 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
certifi==2023.5.7 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
cffi==1.15.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
cfgv==3.3.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
charset-normalizer==3.1.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
click-didyoumean==0.3.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
click-plugins==1.1.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
click-repl==0.2.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
click==8.1.3 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
colorama==0.4.6 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "win32" or python_version >= "3.9" and python_version < "4.0" and platform_system == "Windows"
|
||||||
|
coverage==7.2.5 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
cron-descriptor==1.3.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
decorator==5.1.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
dill==0.3.6 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
distlib==0.3.6 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-celery-beat==2.5.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-cors-headers==3.14.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-coverage-plugin==3.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-debug-toolbar==3.8.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-environ==0.9.0 ; python_version >= "3.9" and python_version < "4"
|
||||||
|
django-extensions==3.2.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-ipware==5.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-location-field==2.7.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-model-utils==4.3.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-polymorphic==3.1.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-redis==5.2.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-structlog==4.1.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-stubs-ext==4.2.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-stubs==1.16.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django-timezone-field==5.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
django==4.2.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
djangorestframework-stubs==1.10.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
djangorestframework==3.14.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
drf-spectacular==0.25.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
executing==1.2.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
factory-boy==3.2.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
faker==18.9.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
filelock==3.12.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
flake8-isort==6.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
flake8==6.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
flower==1.2.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
humanize==4.6.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
identify==2.5.24 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
idna==3.4 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
inflection==0.5.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
iniconfig==2.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
ipdb==0.13.13 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
ipython==8.13.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
isort==5.12.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
jedi==0.18.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
jsonschema==4.17.3 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
kombu==5.2.4 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
lazy-object-proxy==1.9.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
markupsafe==2.1.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
matplotlib-inline==0.1.6 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
mccabe==0.7.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
mypy-extensions==1.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
mypy==0.991 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
nodeenv==1.8.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
packaging==23.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
parso==0.8.3 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pexpect==4.8.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "win32"
|
||||||
|
pickleshare==0.7.5 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pillow==9.5.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
platformdirs==3.5.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pluggy==1.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pre-commit==2.21.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
prometheus-client==0.16.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
prompt-toolkit==3.0.38 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
psutil==5.9.5 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
psycopg2==2.9.6 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "win32"
|
||||||
|
pure-eval==0.2.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pycodestyle==2.10.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pycparser==2.21 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pyflakes==3.0.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pygments==2.15.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pylint-celery==0.3 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pylint-django==2.5.3 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pylint-plugin-utils==0.8.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pylint==2.17.4 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pyrsistent==0.19.3 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pytest-django==4.5.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pytest-sugar==0.9.7 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pytest==7.3.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
python-crontab==2.7.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
python-slugify==7.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pytz==2022.7.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
pyyaml==6.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
redis==4.5.5 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
requests==2.30.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
sentry-sdk==1.23.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
setuptools==67.7.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
six==1.16.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
sniffio==1.3.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
sqlparse==0.4.4 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
stack-data==0.6.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
structlog==23.1.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
termcolor==2.3.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
text-unidecode==1.3 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
tomli==2.0.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
tornado==6.3.2 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
traitlets==5.9.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
types-pytz==2023.3.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
types-pyyaml==6.0.12.9 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
types-requests==2.30.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
types-urllib3==1.26.25.13 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
typing-extensions==4.5.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
tzdata==2023.3 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
uritemplate==4.1.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
urllib3==1.26.15 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
vine==5.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
virtualenv==20.23.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
watchdog==3.0.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
watchfiles==0.18.1 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
wcwidth==0.2.6 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
werkzeug[watchdog]==2.3.4 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
whitenoise==6.4.0 ; python_version >= "3.9" and python_version < "4.0"
|
||||||
|
wrapt==1.15.0 ; python_version >= "3.9" and python_version < "4.0"
|
Loading…
Reference in New Issue
Block a user