def _get_fields_from_method(spore_method):
    fields = []
    required_params = spore_method.get('required_params', [])
    path = spore_method.get('path')
    optional_params = spore_method.get('optional_params', [])

    for param in required_params:
        if re.search(r'\{%s\}' % param, path):
            location = 'path'
        else:
            location = 'query'
        fields.append(
            Field(name=param,
                  required=True,
                  location=location,
                  description=spore_method.get('documentation', '')))

    for param in optional_params:
        fields.append(
            Field(name=param,
                  required=False,
                  location='query',
                  description=spore_method.get('documentation', '')))

    return fields
 def get_manual_fields(self, path, method):
     if method == "GET":
         return []
     elif method == "POST":
         return [
             Field('name'),
             Field('email'),
         ]
 def get_manual_fields(self, path, method):
     if (method == "GET"):
         return []
     elif method == "POST":
         return [
             Field('id', description='user id'),
             Field('code', description='code from sso login')
         ]
 def get_manual_fields(self, path, method):
     if method == "GET":
         return []
     elif method == "PUT":
         return [
             Field('id'),
             Field('token', description='sent via email'),
             Field('email')
         ]
Exemple #5
0
class RateQuery(APIView):
    parser_classes = (JSONParser, XMLParser)
    schema = AutoSchema(manual_fields=[
        Field("start", required=True, schema=coreschema.String()),
        Field("end", required=True, schema=coreschema.String())
    ])
    rate_handler = RateQueryHandler()

    def get(self, request):
        """Get the rate for a given date range
        This is the GET version which accepts query params

        Arguments:
            request {[type]} -- [description]

        Returns:
            integer -- the rate for the given range

        Responses:
            200 -- OK
            404 -- No rate found for range
        """

        return self._handle_request(request.query_params)

    def post(self, request):
        """Get the rate for a given date range
        This is the POST equivalent that accepts a json/xml format

        Arguments:
            request {[type]} -- [description]

        Keyword Arguments:
            format {[type]} -- [description] (default: {None})

        Returns:
            integer -- the rate for the given range

        Responses:
            200 -- OK
            404 -- No rate found for range
        """
        return self._handle_request(request.data)

    def _handle_request(self, data):
        serializer = RateRequestSerializer(data=data)
        if not serializer.is_valid():
            return Response(data=serializer.errors,
                            status=status.HTTP_400_BAD_REQUEST)

        start_time = serializer.validated_data['start']
        end_time = serializer.validated_data['end']
        return self.rate_handler.handle_request(start_time, end_time)
Exemple #6
0
    def get_serializer_fields(self,
                              path,
                              method,
                              view,
                              version=None,
                              method_func=None):
        """
        Return a list of `coreapi.Field` instances corresponding to any
        request body input, as determined by the serializer class.
        """
        if method in ('PUT', 'PATCH', 'POST'):
            location = 'form'
        else:
            location = 'query'

        serializer_class = self.get_serializer_class(view, method_func)
        if not serializer_class:
            return []

        serializer = serializer_class()
        if isinstance(serializer, serializers.ListSerializer):
            return [
                Field(name='data',
                      location=location,
                      required=True,
                      schema=coreschema.Array())
            ]

        if not isinstance(serializer, serializers.Serializer):
            return []

        fields = []
        for field in serializer.fields.values():
            if field.read_only or isinstance(field, serializers.HiddenField):
                continue

            required = field.required and method != 'PATCH'
            # if the attribute ('help_text') of this field is a lazy translation object, force it to generate a string
            description = str(field.help_text) if isinstance(
                field.help_text, Promise) else field.help_text
            fallback_schema = self.fallback_schema_from_field(field)
            field = Field(
                name=field.field_name,
                location=location,
                required=required,
                schema=fallback_schema
                if fallback_schema else field_to_schema(field),
                description=description,
            )
            fields.append(field)

        return fields
Exemple #7
0
 def get_schema_fields(self, view):
     return [
         Field(
             name="name",
             location="query",
             required=False,
             type="string",
             description="book name lookup",
         ),
         Field(
             name="isbn",
             location="query",
             required=False,
             type="string",
             description="ISBN lookup",
         ),
     ]
Exemple #8
0
    def get_response_object(self, response_serializer_class, description):

        fields = []
        serializer = response_serializer_class()
        nested_obj = {}

        for field in serializer.fields.values():
            # If field is a serializer, attempt to get its schema.
            if isinstance(field, serializers.Serializer):
                subfield_schema = self.get_response_object(
                    field.__class__, None)[0].get('schema')

                # If the schema exists, use it as the nested_obj
                if subfield_schema is not None:
                    nested_obj[field.field_name] = subfield_schema
                    nested_obj[
                        field.field_name]['description'] = field.help_text
                    continue

            # Otherwise, carry-on and use the field's schema.
            fallback_schema = self.fallback_schema_from_field(field)
            fields.append(
                Field(
                    name=field.field_name,
                    location='form',
                    required=field.required,
                    schema=fallback_schema
                    if fallback_schema else field_to_schema(field),
                ))

        res = _get_parameters(Link(fields=fields), None)

        if not res:
            if nested_obj:
                return {
                    'description': description,
                    'schema': {
                        'type': 'object',
                        'properties': nested_obj
                    }
                }, {}
            else:
                return {}, {}

        schema = res[0]['schema']
        schema['properties'].update(nested_obj)
        response_schema = {'description': description, 'schema': schema}

        error_status_codes = {}

        response_meta = getattr(response_serializer_class, 'Meta', None)

        for status_code, description in getattr(response_meta,
                                                'error_status_codes',
                                                {}).items():
            error_status_codes[status_code] = {'description': description}

        return response_schema, error_status_codes
Exemple #9
0
class Parameters(object):
    """ Class that holds all parameter schemas
    """
    api_key = Field(
        'api-key',
        location='query',
        required=True,
        schema=String(description='API KEY for access healthsites api.'),
    )

    page = Field(
        'page',
        location='query',
        required=True,
        schema=Integer(
            description='A page number within the paginated result set.'),
    )

    extent = Field(
        'extent',
        location='query',
        required=False,
        schema=String(
            description='Extent of map that is used for filtering data. '
            '(format: minLng, minLat, maxLng, maxLat)'),
    )

    timestamp_from = Field(
        'from',
        location='query',
        required=False,
        schema=Integer(
            description='Get latest modified data from this timestamp.'),
    )

    timestamp_to = Field(
        'to',
        location='query',
        required=False,
        schema=Integer(
            description='Get latest modified data from this timestamp.'),
    )

    country = Field(
        'country',
        location='query',
        required=False,
        schema=String(description='Filter by country'),
    )

    output = Field(
        'output',
        location='query',
        required=False,
        schema=String(
            description=
            'Output format for the request. (json/xml/geojson, default: json)'
        ),
    )
Exemple #10
0
 def get_schema_fields(self, view):
     return [
         Field(
             name="query",
             location="query",
             required=False,
             type="string",
             description="tag initials",
         ),
     ]
Exemple #11
0
    def get_serializer_fields(self, path, method, view, version=None):
        """
        Return a list of `coreapi.Field` instances corresponding to any
        request body input, as determined by the serializer class.
        """
        if method not in ('PUT', 'PATCH', 'POST'):
            return []

        if not hasattr(view, 'serializer_class') and not hasattr(
                view, 'get_serializer_class'):
            return []

        serializer_class = view.get_serializer_class() if hasattr(view, 'get_serializer_class') \
            else view.serializer_class
        serializer = serializer_class()

        if isinstance(serializer, serializers.ListSerializer):
            return [
                Field(name='data',
                      location='body',
                      required=True,
                      schema=coreschema.Array())
            ]

        if not isinstance(serializer, serializers.Serializer):
            return []

        fields = []
        for field in serializer.fields.values():
            if field.read_only or isinstance(field, serializers.HiddenField):
                continue

            required = field.required and method != 'PATCH'
            field = Field(
                name=field.field_name,
                location='form',
                required=required,
                schema=field_to_schema(field),
                description=field.help_text,
            )
            fields.append(field)

        return fields
Exemple #12
0
    def get_manual_fields(self, path, method):
        custom_fields = []
        if method.lower() == "post":
            custom_fields.append(
                Field("message",
                      required=True,
                      location="form",
                      description="message to send to other users"))

        return custom_fields
Exemple #13
0
 def get_manual_fields(self, path, method):
     custom_fields = []
     if method.lower() == "post":
         custom_fields.append(
             Field("direction",
                   required=True,
                   location="form",
                   description="direction to move",
                   example="n"))
     return custom_fields
Exemple #14
0
    def get_manual_fields(self, path, method):
        """Example adding per-method fields."""

        extra_fields = []
        if method == 'POST':
            extra_fields = [
                Field(
                    'username',
                    required=True,
                    location="form",
                ),
                Field(
                    'password',
                    required=True,
                    location="form",
                )
            ]

        manual_fields = super().get_manual_fields(path, method)
        return manual_fields + extra_fields
Exemple #15
0
 def get_link(self, path, method, base_url):
     link = super().get_link(path, method, base_url)
     fields = [
         Field('time_type',
               location='query',
               required=True,
               schema=coreschema.Enum(enum=['year', 'month'])),
         Field('time_value',
               location='query',
               required=True,
               schema=coreschema.String()),
     ]
     fields = tuple(fields)
     link = Link(url=link.url,
                 action=link.action,
                 encoding=link.encoding,
                 fields=fields,
                 description=link.description)
     document.Link()
     return link
Exemple #16
0
def get_note(identifier):
    """
    Return a Document object for a single note instance.
    """
    note = notes[identifier]
    return Document(
        url='/' + identifier,
        title='Note',
        content={
            'description':
            note['description'],
            'complete':
            note['complete'],
            'edit':
            Link(action='put',
                 fields=[Field(name='description'),
                         Field(name='complete')]),
            'delete':
            Link(action='delete')
        })
Exemple #17
0
class GetUserDetailsView(generics.RetrieveAPIView):
    permission_classes = [permissions.IsAuthenticated]
    schema = ManualSchema(fields=[
        Field("employee_id",
              required=True,
              location='query',
              type='integer',
              description='Employee ID id of user')
    ])

    def get(self, request, *args, **kwargs):

        try:
            if request.query_params['employee_id'] == 'me':
                employee_id = self.request.user.employee_id
            else:
                employee_id = int(self.request.query_params['employee_id'])
            user = models.User.objects.get(employee_id=employee_id)
        except ValueError:
            return JsonResponse(
                {
                    'success': False,
                    'message': 'Invalid user id'
                }, status=400)
        except models.User.DoesNotExist:
            return JsonResponse(
                {
                    'success': False,
                    'error': 'User with this id does not exist'
                },
                status=400)
        except MultiValueDictKeyError:
            return JsonResponse(
                {
                    'success': False,
                    'message': 'Parameter value "employee_id" is required'
                },
                status=400)
        try:
            serializer = serializers.GetUserDetailInfoSerializer(user)
            return Response({
                'success': True,
                'data': serializer.data
            },
                            status=status.HTTP_200_OK)

        except Exception:
            return JsonResponse(
                {
                    'success': False,
                    'message': 'Error occurred in getting user data!'
                },
                status=500)
def test_get_with_path_parameter(monkeypatch, http):
    def mockreturn(self, request):
        insert = request.url.encode('utf-8')
        return MockResponse(b'{"_type": "document", "example": "' + insert +
                            b'"}')

    monkeypatch.setattr(requests.Session, 'send', mockreturn)

    link = Link(url='http://example.org/{user_id}/',
                action='get',
                fields=[Field(name='user_id', location='path')])
    doc = http.transition(link, decoders, params={'user_id': 123})
    assert doc == {'example': 'http://example.org/123/'}
    def get_path_fields(self, path, method, view):
        """
        Return a list of `coreapi.Field` instances corresponding to any
        templated path variables.
        """
        model = getattr(getattr(view, 'queryset', None), 'model', None)
        fields = []

        for variable in uritemplate.variables(path):

            if variable == 'version':
                continue

            title = ''
            description = ''
            schema_cls = coreschema.String
            kwargs = {}
            if model is not None:
                # Attempt to infer a field description if possible.
                try:
                    model_field = model._meta.get_field(variable)
                except:
                    model_field = None

                if model_field is not None and hasattr(model_field,
                                                       'verbose_name'):
                    title = force_text(model_field.verbose_name)

                if model_field is not None and hasattr(model_field,
                                                       'help_text'):
                    description = force_text(model_field.help_text)
                elif model_field is not None and hasattr(
                        model_field, 'primary_key'):
                    description = get_pk_description(model, model_field)

                if hasattr(view, 'lookup_value_regex'
                           ) and view.lookup_field == variable:
                    kwargs['pattern'] = view.lookup_value_regex
                elif isinstance(model_field, models.AutoField):
                    schema_cls = coreschema.Integer

            field = Field(name=variable,
                          location='path',
                          required=True,
                          schema=schema_cls(title=title,
                                            description=description,
                                            **kwargs))
            fields.append(field)

        return fields
Exemple #20
0
def get_notes():
    """
    Return the top level Document object, containing all the note instances.
    """
    return Document(
        url='/',
        title='Notes',
        content={
            'notes':
            [get_note(identifier) for identifier in reversed(notes.keys())],
            'add_note':
            Link(action='post',
                 fields=[Field(name='description', required=True)])
        })
Exemple #21
0
    def get_manual_fields(self, path, method):
        """Example adding per-method fields."""

        extra_fields = []
        if method == 'POST':
            extra_fields = [
                Field(
                    'account',
                    description="receptor account number.",
                    location="form",
                )
            ]

        manual_fields = super().get_manual_fields(path, method)
        return manual_fields + extra_fields
Exemple #22
0
def get_link(route: Route) -> Link:
    """
    Given a single route, return a Link instance containing all the information
    needed to expose that route in an API Schema.
    """
    path, method, view = route

    view_signature = inspect.signature(view)
    uritemplate = URITemplate(path)

    description = _get_link_description(view)

    fields = []
    for param in view_signature.parameters.values():

        if param.annotation is inspect.Signature.empty:
            annotated_type = str
        else:
            annotated_type = param.annotation

        location = None
        required = False
        param_schema = _annotated_type_to_coreschema(annotated_type)
        if param.name in uritemplate.variable_names:
            location = 'path'
            required = True
        elif (annotated_type in primitive_types) or issubclass(
                annotated_type, schema_types):
            if method in ('POST', 'PUT', 'PATCH'):
                if issubclass(annotated_type, schema.Object):
                    location = 'body'
                    required = True
                else:
                    location = 'form'
            else:
                location = 'query'

        if location is not None:
            field = Field(name=param.name,
                          location=location,
                          required=required,
                          schema=param_schema)
            fields.append(field)

    return Link(url=path,
                action=method,
                description=description,
                fields=fields)
Exemple #23
0
    def get_response_object(self, response_serializer_class, description):

        fields = []
        serializer = response_serializer_class()
        nested_obj = {}

        for field in serializer.fields.values():
            if isinstance(field, serializers.Serializer):
                nested_obj[field.field_name] = self.get_response_object(
                    field.__class__, None)[0]['schema']
                nested_obj[field.field_name]['description'] = field.help_text
                continue

            fields.append(
                Field(name=field.field_name,
                      location='form',
                      required=field.required,
                      schema=field_to_schema(field)))

        res = _get_parameters(Link(fields=fields), None)

        if not res:
            if nested_obj:
                return {
                    'description': description,
                    'schema': {
                        'type': 'object',
                        'properties': nested_obj
                    }
                }, {}
            else:
                return {}, {}

        schema = res[0]['schema']
        schema['properties'].update(nested_obj)
        response_schema = {'description': description, 'schema': schema}

        error_status_codes = {}

        response_meta = getattr(response_serializer_class, 'Meta', None)

        for status_code, description in getattr(response_meta,
                                                'error_status_codes',
                                                {}).items():
            error_status_codes[status_code] = {'description': description}

        return response_schema, error_status_codes
Exemple #24
0
 def test_mocking(self):
     content = {
         'test': {
             'post_data':
             Link(url='/post_data/',
                  action='post',
                  fields=[Field('data', location='body')]),
         }
     }
     schema = Document(title='test', content=content)
     mock.add(schema, ['test', 'post_data'], {"a": 1})
     client = DjangoCoreAPIClient()
     doc = client.action(schema, ['test', 'post_data'],
                         params={'data': {
                             'test': 'cat'
                         }})
     self.assertEqual(doc, {"a": 1})
Exemple #25
0
    def test_post_data(self):
        content = {
            'test': {
                'post_data':
                Link(url='/post_data/',
                     action='post',
                     fields=[Field('data', location='body')]),
            }
        }
        schema = Document(title='test', content=content)

        client = DjangoCoreAPIClient()
        doc = client.action(schema, ['test', 'post_data'],
                            params={'data': {
                                'test': 'cat'
                            }})
        self.assertIsNotNone(doc)
def test_document_equality(doc):
    assert doc == {
        'integer':
        123,
        'dict': {
            'key': 'value'
        },
        'list': [1, 2, 3],
        'link':
        Link(url='/',
             action='post',
             transform='inplace',
             fields=[
                 'optional',
                 Field('required', required=True, location='path')
             ]),
        'nested': {
            'child': Link(url='/123')
        }
    }
Exemple #27
0
    def get_link(self, path, method, base_url):
        link = super().get_link(path, method, base_url)
        # 无法指定bill_ids数组中的元素类型,这里元素定义为int但实际为str,无法处理...
        batch_del_fields = [
            Field('bill_ids',
                  location='form',
                  required=True,
                  schema=coreschema.Array(items=coreschema.Integer(),
                                          unique_items=True))
        ]
        fields = link.fields
        if link.url == '/api/v1/bills/batch/' and method.lower() == 'delete':
            fields = tuple(batch_del_fields)

        link = Link(url=link.url,
                    action=link.action,
                    encoding=link.encoding,
                    fields=fields,
                    description=link.description)
        document.Link()
        return link
def doc():
    return Document(url='http://example.org',
                    title='Example',
                    content={
                        'integer':
                        123,
                        'dict': {
                            'key': 'value'
                        },
                        'list': [1, 2, 3],
                        'link':
                        Link(url='/',
                             action='post',
                             transform='inplace',
                             fields=[
                                 'optional',
                                 Field('required',
                                       required=True,
                                       location='path')
                             ]),
                        'nested': {
                            'child': Link(url='/123')
                        }
                    })
Exemple #29
0
]

app = App(routes=routes)

client = TestClient(app)

expected = Schema(
    url='/schema/',
    content={
        'list_todo':
        Link(url='/todo/',
             action='GET',
             description='list_todo description',
             fields=[
                 Field(name='search',
                       location='query',
                       required=False,
                       schema=coreschema.String())
             ]),
        'add_todo':
        Link(url='/todo/',
             action='POST',
             description='add_todo description\nMultiple indented lines',
             fields=[
                 Field(name='note',
                       location='body',
                       required=True,
                       schema=coreschema.String())
             ]),
        'show_todo':
        Link(url='/todo/{ident}/',
             action='GET',
Exemple #30
0
    def get_manual_fields(self, path, method):
        extra_fields = []
        if method == 'GET' and 'id' not in path:
            extra_fields = [
                Field(
                    'active',
                    required=False,
                    location='query',
                    schema=coreschema.String(
                        description=
                        'Boolean, if set will only show bookables marked as "Active"'
                    )),
                Field(
                    'mine',
                    required=False,
                    location='query',
                    schema=coreschema.String(
                        description=
                        'Boolean, if set will only show bookables for hosts with the current user as the owner'
                    )),
                Field(
                    'mygroup',
                    required=False,
                    location='query',
                    schema=coreschema.String(
                        description=
                        'Boolean, if set will only show bookables for hosts assigned to one of the user\'s groups'
                    )),
                Field('lab',
                      required=False,
                      location='query',
                      schema=coreschema.String(
                          description='Filter only those in lab ID')),
                Field('building',
                      required=False,
                      location='query',
                      schema=coreschema.String(
                          description='Filter only those in building ID')),
                Field(
                    'hw',
                    required=False,
                    location='query',
                    schema=coreschema.String(
                        description='Filter only those with HostHardware of ID'
                    )),
                Field('htype',
                      required=False,
                      location='query',
                      schema=coreschema.String(
                          description='Filter only those in HostType of ID')),
                Field('lab',
                      required=False,
                      location='query',
                      schema=coreschema.String(
                          description='Filter only those in lab ID')),
                Field(
                    'nores',
                    required=False,
                    location='query',
                    schema=coreschema.String(
                        description=
                        'Boolean, if set will exclude bookables that are reserved'
                    )),
                Field(
                    'free',
                    required=False,
                    location='query',
                    schema=coreschema.String(
                        description=
                        'Boolean, if set will only show bookables that are free to book now'
                    )),
            ]

        manual_fields = super().get_manual_fields(path, method)
        return manual_fields + extra_fields