Example #1
0
 def __init__(self):
     self.application_title = get_avishan_config().OPENAPI_APPLICATION_TITLE
     self.application_description = get_avishan_config().OPENAPI_APPLICATION_DESCRIPTION
     self.application_version = get_avishan_config().OPENAPI_APPLICATION_VERSION
     self.application_servers = get_avishan_config().OPENAPI_APPLICATION_SERVERS
     self.project: Project = get_avishan_config().PROJECT
     self.models: List[DjangoAvishanModel] = sorted(self.project.models_pool(), key=lambda x: x.name)
    def __init__(self, get_response):
        from avishan.configure import get_avishan_config

        self.get_response = get_response
        get_avishan_config().on_startup()
        """Run Descriptor to find any error in startup and store project"""
        from avishan.descriptor import Project
        self.project = Project(name=get_avishan_config().PROJECT_NAME)
        get_avishan_config().PROJECT = self.project
Example #3
0
 def load_apps(self) -> List['DjangoApplication']:
     from avishan.configure import get_avishan_config
     return [
         DjangoApplication(project=self, name=app_name)
         for app_name in settings.INSTALLED_APPS if app_name not in
         get_avishan_config().descriptor_ignored_installed_apps()
     ]
Example #4
0
    def export(self) -> dict:
        if self.name:
            return {
                "$ref": f"#/components/schemas/{self.name}"
            }
        data = {
            'type': self.type,
            'description': ""
        }
        if self.type == 'integer':
            data['minimum'] = 1
            data['maximum'] = 9223372036854775807
        if self.format:
            data['format'] = self.format
        if self.default is not Attribute.NO_DEFAULT:
            data['default'] = self.default
        if self.description:
            data['description'] = self.description
        if self.items:
            data['items'] = self.items.export()
        if self.enum:
            enum = 'Enum: '
            for item in self.enum:
                enum += f"`{item}`, "
            data['description'] = enum[:-2] + "." + data['description']

        if len(data['description']) == 0:
            del data['description']

        if len(self.properties) > 0:
            data['properties'] = {}
            data['required'] = []
            for item in self.properties:
                if item.required:
                    data['required'].append(item.name)
                data['properties'][item.name] = item.export()
                if not item.required:
                    data['properties'][item.name]['nullable'] = True
            if len(data['required']) == 0:
                del data['required']

        if self.type == 'string' and self.format == 'date-time':
            data['example'] = timezone.now().strftime(get_avishan_config().DATETIME_STRING_FORMAT)
        if self.type == 'string' and self.format == 'date':
            data['example'] = timezone.now().strftime(get_avishan_config().DATE_STRING_FORMAT)

        return data
 def setup(self, request, *args, **kwargs):
     super().setup(request, *args, **kwargs)
     self.context = {
         **self.context,
         **{
             'CURRENT_REQUEST': request,
             'AVISHAN_CONFIG': get_avishan_config(),
             'self': self
         }
     }
    def __init__(self, request: WSGIRequest):
        from avishan.views.class_based import AvishanView, AvishanTemplateView
        from avishan.models import BaseUser, UserGroup, UserUserGroup, EmailKeyValueAuthentication, \
            PhoneKeyValueAuthentication, EmailOtpAuthentication, PhoneOtpAuthentication, VisitorKeyAuthentication, \
            RequestTrack
        from avishan.descriptor import Project
        from avishan.configure import get_avishan_config
        from avishan.exceptions import AvishanException

        self.project: Optional[Project] = None
        self.request: WSGIRequest = request
        self.response: dict = {}
        self.parsed_data: Optional[dict] = None
        self.language: str = request.GET.get('language') or request.GET.get(
            'lng') or get_avishan_config().LANGUAGE
        self.can_touch_response: bool = True
        self.is_tracked: bool = True
        self.add_token: bool = False

        self.is_api: Optional[bool] = None
        self.view_class: Optional[AvishanView] = None
        self.on_error_view_class: Optional[AvishanTemplateView] = None
        self.json_unsafe: bool = False
        self.token: Optional[str] = None
        self.decoded_token: Optional[dict] = None
        self.status_code: int = 200
        self.context: dict = {}
        self.messages: dict = {
            'debug': [],
            'info': [],
            'success': [],
            'warning': [],
            'error': []
        }

        self.start_time: datetime.datetime = timezone.now()
        self.end_time: Optional[datetime.datetime] = None
        self.view_start_time: Optional[datetime.datetime] = None
        self.view_end_time: Optional[datetime.datetime] = None

        self.base_user: Optional[BaseUser] = None
        self.user_group: Optional[UserGroup] = None
        self.user_user_group: Optional[UserUserGroup] = None
        self.authentication_object: Optional[
            Union[EmailKeyValueAuthentication, PhoneKeyValueAuthentication,
                  EmailOtpAuthentication, PhoneOtpAuthentication,
                  VisitorKeyAuthentication]] = None

        self.request_track_object: RequestTrack = RequestTrack()
        self.exception: Optional[AvishanException] = None
        self.traceback: Optional[str] = None
        self.debug: bool = False
Example #7
0
    def __init__(self,
                 model: type,
                 target_name: str,
                 response_json_key: str,
                 url: str = None,
                 method: ApiMethod.METHOD = ApiMethod.METHOD.GET,
                 authenticate: bool = True,
                 hide_in_redoc: bool = False,
                 is_class_method: bool = None,
                 documentation: 'ApiDocumentation' = None):
        from avishan.configure import get_avishan_config
        from avishan.models import AvishanModel
        model: AvishanModel

        if url is None:
            auto_set_url = True
            url = f'/{target_name}'
        else:
            auto_set_url = False

        super().__init__(target=getattr(model, target_name),
                         url='/' + get_avishan_config().AVISHAN_URLS_START +
                         f'/{model.class_plural_snake_case_name()}' + url,
                         method=method)

        self.model = model
        self.authenticate = authenticate
        self.hide_in_redoc = hide_in_redoc
        self.response_json_key = response_json_key
        if is_class_method is not None:
            self.is_class_method = is_class_method

        if not self.is_class_method and auto_set_url:
            self.url = '/' + get_avishan_config().AVISHAN_URLS_START + f'/{model.class_plural_snake_case_name()}/' \
                       + '{id}' + url

        self.documentation = documentation
Example #8
0
    def __str__(self):

        try:
            if get_current_request().avishan.language is None:
                lang = get_avishan_config().LANGUAGE
            else:
                lang = get_current_request().avishan.language
            if lang.upper() in self.__dict__.keys() and self.__dict__[
                    lang.upper()] is not None:
                return self.__dict__[lang.upper()]
        except:
            pass
        try:
            return list(self.__dict__.values())[0]
        except IndexError:
            return 'NOT_TRANSLATED_STRING'
Example #9
0
def send_template_sms(
        phone: Phone,
        template_name: str,
        token: str,
        token2: str = None,
        token3: str = None,
        api_key: Optional[str] = get_avishan_config().KAVENEGAR_API_TOKEN):
    data = {'receptor': phone.key, 'template': template_name, 'token': token}
    if token2 is not None:
        data['token2'] = token2
    if token3 is not None:
        data['token3'] = token3

    response = requests.post(
        url=f"https://api.kavenegar.com/v1/{api_key}/verify/lookup.json",
        data=data)
    if response.status_code != 200:
        print(response.text)
Example #10
0
    def __init__(self):
        self.packs = []
        for item in get_avishan_config().CHAYI_PROJECT_PACKAGE:
            self.packs.append([
                item[0], f'package {item[1]}.models;\n\n'
                f'import {item[1]}.constants.Constants;\n'
            ])

        self.files = {}
        self.tab_size = 0
        for model in AvishanModel.get_models():
            if model._meta.abstract or model.export_ignore:
                continue
            self.files[model.class_name() +
                       ".java"] = self.model_file_creator(model)

        self.model_file_predefined_models(self.files)

        self.compress_files(self.packs, self.files)
Example #11
0
def send_raw_sms(
        phone: Union[Phone, List[Phone]],
        text: str,
        api_key: Optional[str] = get_avishan_config().KAVENEGAR_API_TOKEN):
    receptor = ""
    if isinstance(phone, Phone):
        receptor = phone.key
    else:
        for item in phone:
            receptor += item.key + ","
        if len(phone) > 0:
            receptor = receptor[:-1]
    if len(receptor) == 0:
        raise ErrorMessageException(message=AvishanTranslatable(
            EN='Empty receptor numbers', FA='لیست دریافت کننده‌ها خالی است'))

    data = {'receptor': receptor, 'message': text}

    response = requests.post(
        url=f"https://api.kavenegar.com/v1/{api_key}/sms/send.json", data=data)
    if response.status_code != 200:
        print(response.text)
Example #12
0
    def _export_paths(self) -> dict:
        data = {}
        for model in self.models:
            if model.name in get_avishan_config().get_openapi_ignored_path_models():
                continue
            for direct_callable in model.direct_callables:
                direct_callable: DirectCallable
                if direct_callable.hide_in_redoc or direct_callable.documentation is None:
                    continue
                if direct_callable.url not in data.keys():
                    data[direct_callable.url] = Path(url=direct_callable.url)

                setattr(data[direct_callable.url], direct_callable.method.name.lower(), Operation(
                    summary=direct_callable.documentation.title,
                    description=direct_callable.documentation.description,
                    request_body=Operation.extract_request_body_from_direct_callable(direct_callable),
                    responses=Operation.extract_responses_from_direct_callable(direct_callable),
                    tags=[stringcase.titlecase(model.name)]
                ))

        for key, value in data.items():
            data[key] = value.export()

        return data
Example #13
0
def distance_matrix(origins: List[Tuple[float, float]], destinations: List[Tuple[float, float]]) -> \
        List[List[Tuple[float, float]]]:
    if len(origins) == 0 or len(destinations) == 0:
        raise ValueError('length of entered lists can\'t be 0')
    origins_text = ''
    for item in origins:
        origins_text += f'%7C{item[0]},{item[1]}'
    destinations_text = ''
    for item in destinations:
        destinations_text += f'%7C{item[0]},{item[1]}'

    url = f'https://api.neshan.org/v1/distance-matrix?' \
          f'origins={origins_text[3:]}&destinations={destinations_text[3:]}'
    response = requests.get(url=url,
                            headers={
                                'Api-Key': get_avishan_config().NESHAN_API_KEY
                            }).json()

    data = []
    for row in response['rows']:
        data.append([(element['distance']['value'],
                      element['duration']['value'])
                     for element in row['elements']])
    return data
 def _remove_authenticate(cls) -> bool:
     from avishan.configure import get_avishan_config
     return get_avishan_config().CRUD_AUTHENTICATE.get(cls.class_name(), cls.DEFAULT_CRUD_DICT).get('remove', True)
Example #15
0
    def save_request_track(request: WSGIRequest):
        from avishan.configure import get_avishan_config
        # noinspection PyTypeHints
        request.avishan: AvishanRequestStorage
        from avishan.models import RequestTrackException
        for ignore in get_avishan_config().IGNORE_TRACKING_STARTS:
            if request.get_full_path().startswith(ignore) and \
                    request.avishan.request_track_object:
                request.avishan.request_track_object.delete()
                return
        request.avishan.end_time = timezone.now()

        authentication_type_class_title = "NOT_AVAILABLE"
        authentication_type_object_id = 0
        if request.avishan.authentication_object:
            authentication_type_class_title = request.avishan.authentication_object.__class__.__name__
            authentication_type_object_id = request.avishan.authentication_object.id

        request_data = "NOT_AVAILABLE"
        request_data_size = -1
        if request.method in ['POST', 'PUT']:
            try:
                request_data = json.dumps(request.data, indent=2)
                request_data_size = sys.getsizeof(json.dumps(request.data))
            except:
                print("*DEBUG* request parse error")

        request_headers = ""
        for key, value in request.META.items():
            if key.startswith('HTTP_'):
                request_headers += f'{key[5:]}={value}\n'
        for key in request.FILES.keys():
            request_headers += f'FILE({key})\n'

        from avishan.views.class_based import AvishanView
        if request.avishan.view_class:
            view_name = request.avishan.view_class.__class__.__name__ \
                if isinstance(request.avishan.view_class, AvishanView) \
                else request.avishan.view_class.__name__
        else:
            view_name = None

        try:
            response_data = json.dumps(request.avishan.response, indent=2)
        except:
            print("*DEBUG* response parse error:", request.avishan.response)
            response_data = 'NOT_AVAILABLE'

        from avishan.models import UserUserGroup
        if request.avishan.user_user_group:
            try:
                uug = UserUserGroup.objects.get(
                    id=request.avishan.user_user_group.id)
            except UserUserGroup.DoesNotExist:
                uug = None
        else:
            uug = None
        try:
            created = request.avishan.request_track_object.update(
                view_name=view_name,
                url=request.get_full_path(),
                status_code=request.avishan.status_code,
                method=request.method,
                json_unsafe=request.avishan.json_unsafe,
                is_api=request.avishan.is_api,
                add_token=request.avishan.add_token,
                user_user_group=uug,
                request_data=request_data,
                request_data_size=request_data_size,
                request_headers=request_headers,
                response_data=response_data,
                response_data_size=sys.getsizeof(response_data),
                start_time=request.avishan.start_time,
                end_time=request.avishan.end_time,
                total_execution_milliseconds=int(
                    (request.avishan.end_time -
                     request.avishan.start_time).total_seconds() * 1000),
                view_execution_milliseconds=int(
                    (request.avishan.view_end_time -
                     request.avishan.view_start_time).total_seconds() *
                    1000) if request.avishan.view_end_time else 0,
                authentication_type_class_title=authentication_type_class_title,
                authentication_type_object_id=authentication_type_object_id)

            if request.avishan.exception is not None:
                RequestTrackException.objects.create(
                    request_track=created,
                    class_title=request.avishan.exception.__class__.__name__,
                    args=request.avishan.exception.args,
                    traceback=request.avishan.traceback)
        except Exception as e:
            print('save_request_track_error:'.upper(), e)
Example #16
0
 def model_file_head_imports() -> str:
     return get_avishan_config().CHAYI_MODEL_FILE_IMPORTS
Example #17
0
class AvishanFaker:
    _faker = Faker(locale=get_avishan_config().FAKER_LOCALE)
    Faker.seed(get_avishan_config().FAKER_SEED)

    @classmethod
    def fake_it(cls, **overriding):
        data = {}
        for key, value in cls.faker_get_create_params_dict().items():

            if callable(getattr(cls, f'_{key}_fake', None)):
                data[key] = getattr(cls, f'_{key}_fake')()
            else:
                if key in overriding.keys():
                    if callable(overriding[key]):
                        faking_method = overriding[key]
                    else:
                        faking_method = None
                else:
                    faking_method = cls.faker_assign_faking_method(key, value)

                if not faking_method:
                    data[key] = overriding[key]
                else:
                    data[key] = faking_method()

        created = cls.faker_get_create_method()(**data)
        if not hasattr(cls, 'fakes'):
            cls.fakes = []
        cls.fakes.append(created)
        return created

    @classmethod
    def fake_list(cls, count: int = 5, **overriding):
        return [cls.fake_it(**overriding) for _ in range(count)]

    @classmethod
    def faker_generate(cls, count: int = 5):
        if not hasattr(cls, 'fakes'):
            cls.fakes = []
        cls.fake_list(count=count - len(cls.fakes))
        return cls.fakes

    @classmethod
    def faker_get_create_params_dict(cls) -> Dict[str, Parameter]:
        return dict(
            inspect.signature(
                cls.faker_get_create_method()).parameters.items())

    @classmethod
    def faker_get_create_method(cls) -> Callable:
        from avishan.models import AvishanModel
        cls: Union[AvishanFaker, AvishanModel]
        return cls.create

    @classmethod
    def faker_assign_faking_method(cls, key: str,
                                   value: Parameter) -> Callable:
        from avishan.models import AvishanModel

        if not isinstance(value, Parameter):
            raise ValueError(
                f'parameter {key} in class {cls.__name__} should have type hint to fake it.'
            )
        if key == 'kwargs':
            raise ValueError(f'kwargs in class {cls.__name__} is not valid')

        if value.default is None:
            return lambda: None

        if isinstance(value.annotation, models.base.ModelBase):
            if issubclass(value.annotation, AvishanModel):
                return lambda: value.annotation.fake_it()
            raise NotImplementedError()

        try:
            return {
                bool: cls._bool_fake,
                str: cls._str_fake,
                int: cls._int_fake,
                float: cls._float_fake,
                datetime: cls._datetime_fake,
                date: cls._date_fake,
                time: cls._time_fake
            }[value.annotation]
        except KeyError:
            pass

        if isinstance(value.annotation.__args__[0], ForwardRef):
            list_of = AvishanModel.get_model_with_class_name(
                value.annotation.__args__[0].__forward_arg__)
        else:
            list_of = value.annotation.__args__[0]
        return lambda: list_of.fake_list()

    @classmethod
    def _bool_fake(cls) -> bool:
        return cls._faker.pybool()

    @classmethod
    def _str_fake(cls) -> str:
        return " ".join(cls._faker.words(8))

    @classmethod
    def _int_fake(cls) -> int:
        return cls._faker.pyint(min_value=0, max_value=100000)

    @classmethod
    def _float_fake(cls,
                    left_digits: Optional[int] = 2,
                    right_digits: Optional[int] = 2,
                    positive: Optional[bool] = True,
                    min_value: Optional[float] = 0,
                    max_value: Optional[float] = None) -> float:
        return cls._faker.pyfloat(left_digits=left_digits,
                                  right_digits=right_digits,
                                  positive=positive,
                                  min_value=min_value,
                                  max_value=max_value)

    @classmethod
    def _datetime_fake(cls) -> datetime:
        return cls._faker.date_time()

    @classmethod
    def _date_fake(cls) -> date:
        return cls._faker.date_object()

    @classmethod
    def _time_fake(cls) -> time:
        return cls._faker.time_object()
Example #18
0
from requests import post, Response
from avishan.configure import get_avishan_config

FIREBASE_SERVER_TOKEN = get_avishan_config().FIREBASE_SERVER_TOKEN


def send_firebase_data_message(
        data: dict,
        to_key: str,
        server_key: str = FIREBASE_SERVER_TOKEN) -> Response:
    return post(url='https://fcm.googleapis.com/fcm/send',
                json={
                    "data": data,
                    'to': to_key,
                    "android": {
                        "priority": "high"
                    },
                },
                headers={'Authorization': f'key={server_key}'})


def send_firebase_notification(title: str,
                               body: str,
                               to_key: str,
                               server_key: str = FIREBASE_SERVER_TOKEN):
    return post(url='https://fcm.googleapis.com/fcm/send',
                json={
                    "notification": {
                        "title": title,
                        "body": body
                    },
 def get_app_names() -> List[str]:
     from django.apps import apps
     from avishan.configure import get_avishan_config
     return [key.name for key in apps.get_app_configs() if
             key.name in get_avishan_config().MONITORED_APPS_NAMES]
Example #20
0
    def __call__(self, request: WSGIRequest):
        from avishan.utils import discard_monitor, find_token, decode_token, add_token_to_response, find_and_check_user
        from avishan.exceptions import AvishanException
        from avishan.exceptions import save_traceback
        from avishan.configure import get_avishan_config

        request.avishan = AvishanRequestStorage(request)
        request.avishan.project = self.project
        """Checks for avoid-touch requests"""
        if discard_monitor(request.get_full_path()):
            print(f"NOT_MONITORED: {request.get_full_path()}")
            response = self.get_response(request)
            if 'token' in request.COOKIES.keys():
                response.set_cookie('token', request.COOKIES['token'])
            del request.avishan
            return response
        """Find token and parse it"""
        """
        Bara inke yadam nare. tooye sathe middleware vaghti error midim, chon nemidoonim api e ya template, error ro 
        zakhire mikonim mirim decorator, baad oonja k set shod in meghdar, check mikonim chon error hast, barmigarde 
        inja 
        """
        try:
            if find_token():
                decode_token()
                find_and_check_user()
        except AvishanException:
            pass
        except Exception as e:
            save_traceback()
            AvishanException(e)

        get_avishan_config().on_request(request)

        # todo 0.2.2 check for 'avishan_' in request bodies
        """Send request object to the next layer and wait for response"""
        try:
            response = self.get_response(request)
            if not request.avishan.can_touch_response:
                del request.avishan
                return response
        except AvishanException:
            pass
        except Exception as e:
            save_traceback()
            AvishanException(e)

        remove_from_crum = False
        if get_current_request() is None:
            remove_from_crum = True
            set_current_request(request)
        """messages"""
        if request.avishan.have_message():
            # todo 0.2.3: check for debug=True

            if request.avishan.is_api:
                request.avishan.response['messages'] = request.avishan.messages
            else:
                # noinspection PyTypeChecker
                self.fill_messages_framework(request)
                if request.avishan.on_error_view_class and response.status_code == 500:
                    response = request.avishan.on_error_view_class.render()
                # todo fix problem on template: not showing thrown exception message

        add_token_to_response(response)
        status_code = request.avishan.status_code
        is_api = request.avishan.is_api
        json_safe = not request.avishan.json_unsafe
        if is_api:
            response = request.avishan.response.copy()

        if request.avishan.is_tracked or request.avishan.exception is not None:
            self.save_request_track(request)

        del request.avishan
        if remove_from_crum:
            set_current_request(None)

        if is_api:
            return JsonResponse(response, status=status_code, safe=json_safe)
        """Do not change redirection status codes"""
        if response.status_code // 100 != 3:
            response.status_code = status_code
        return response