def field_to_schema(field): title = force_text(field.label) if field.label else '' description = force_text(field.help_text) if field.help_text else '' if isinstance(field, serializers.ListSerializer): child_schema = field_to_schema(field.child) return coreschema.Array(items=child_schema, title=title, description=description) elif isinstance(field, serializers.Serializer): return coreschema.Object(properties=OrderedDict([ (key, field_to_schema(value)) for key, value in field.fields.items() ]), title=title, description=description) elif isinstance(field, serializers.ManyRelatedField): return coreschema.Array(items=coreschema.String(), title=title, description=description) elif isinstance(field, serializers.RelatedField): return coreschema.String(title=title, description=description) elif isinstance(field, serializers.MultipleChoiceField): return coreschema.Array( items=coreschema.Enum(enum=list(field.choices.keys())), title=title, description=description) elif isinstance(field, serializers.ChoiceField): return coreschema.Enum(enum=list(field.choices.keys()), title=title, description=description) elif isinstance(field, serializers.BooleanField): return coreschema.Boolean(title=title, description=description) elif isinstance(field, (serializers.DecimalField, serializers.FloatField)): return coreschema.Number(title=title, description=description) elif isinstance(field, serializers.IntegerField): return coreschema.Integer(title=title, description=description) if field.style.get('base_template') == 'textarea.html': return coreschema.String(title=title, description=description, format='textarea') return coreschema.String(title=title, description=description)
def get_serializer_fields(self, path, method): """ Return a list of `coreapi.Field` instances corresponding to any request body input, as determined by the serializer class. """ view = self.view if method not in ('PUT', 'PATCH', 'POST'): return [] if not hasattr(view, 'get_serializer'): return [] try: serializer = view.get_serializer() except exceptions.APIException: serializer = None warnings.warn('{}.get_serializer() raised an exception during ' 'schema generation. Serializer fields will not be ' 'generated for {} {}.' .format(view.__class__.__name__, method, path)) if isinstance(serializer, serializers.ListSerializer): return [ coreapi.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 = coreapi.Field( name=field.field_name, location='form', required=required, schema=field_to_schema(field) ) fields.append(field) return fields
def get_serializer_fields(self, path, method, view): """ 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, 'get_serializer'): return [] serializer = view.get_serializer() if isinstance(serializer, serializers.ListSerializer): return [ coreapi.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 = coreapi.Field( name=field.field_name, location='form', required=required, schema=field_to_schema(field) ) fields.append(field) return fields
def field_to_schema(field): title = force_text(field.label) if field.label else '' description = force_text(field.help_text) if field.help_text else '' if isinstance(field, (serializers.ListSerializer, serializers.ListField)): child_schema = field_to_schema(field.child) return coreschema.Array(items=child_schema, title=title, description=description) elif isinstance(field, serializers.DictField): return coreschema.Object(title=title, description=description) elif isinstance(field, serializers.Serializer): return coreschema.Object(properties=OrderedDict([ (key, field_to_schema(value)) for key, value in field.fields.items() ]), title=title, description=description) elif isinstance(field, serializers.ManyRelatedField): return coreschema.Array(items=coreschema.String(), title=title, description=description) elif isinstance(field, serializers.PrimaryKeyRelatedField): schema_cls = coreschema.String model = getattr(field.queryset, 'model', None) if model is not None: model_field = model._meta.pk if isinstance(model_field, models.AutoField): schema_cls = coreschema.Integer return schema_cls(title=title, description=description) elif isinstance(field, serializers.RelatedField): return coreschema.String(title=title, description=description) elif isinstance(field, serializers.MultipleChoiceField): return coreschema.Array( items=coreschema.Enum(enum=list(field.choices)), title=title, description=description) elif isinstance(field, serializers.ChoiceField): return coreschema.Enum(enum=list(field.choices), title=title, description=description) elif isinstance(field, serializers.BooleanField): return coreschema.Boolean(title=title, description=description) elif isinstance(field, (serializers.DecimalField, serializers.FloatField)): return coreschema.Number(title=title, description=description) elif isinstance(field, serializers.IntegerField): return coreschema.Integer(title=title, description=description) elif isinstance(field, serializers.DateField): return coreschema.String(title=title, description=description, format='date') elif isinstance(field, serializers.DateTimeField): return coreschema.String(title=title, description=description, format='date-time') elif isinstance(field, serializers.JSONField): return coreschema.Object(title=title, description=description) if field.style.get('base_template') == 'textarea.html': return coreschema.String(title=title, description=description, format='textarea') return coreschema.String(title=title, description=description)
def test_authenticated_request(self): client = APIClient() client.force_authenticate(MockUser()) response = client.get('/', HTTP_ACCEPT='application/coreapi+json') assert response.status_code == 200 expected = coreapi.Document( url='http://testserver/', title='Example API', content={ 'example': { 'list': coreapi.Link( url='/example/', action='get', fields=[ coreapi.Field( 'page', required=False, location='query', schema=coreschema.Integer( title='Page', description= 'A page number within the paginated result set.' )), coreapi.Field( 'page_size', required=False, location='query', schema=coreschema.Integer( title='Page size', description= 'Number of results to return per page.')), coreapi.Field( 'ordering', required=False, location='query', schema=coreschema.String( title='Ordering', description= 'Which field to use when ordering the results.' )) ]), 'create': coreapi.Link( url='/example/', action='post', encoding='application/json', fields=[ coreapi.Field( 'a', required=True, location='form', schema=coreschema.String( title='A', description='A field description')), coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')) ]), 'read': coreapi.Link( url='/example/{id}/', action='get', fields=[ coreapi.Field('id', required=True, location='path', schema=coreschema.String()), coreapi.Field( 'ordering', required=False, location='query', schema=coreschema.String( title='Ordering', description= 'Which field to use when ordering the results.' )) ]), 'custom_action': coreapi.Link( url='/example/{id}/custom_action/', action='post', encoding='application/json', description='A description of custom action.', fields=[ coreapi.Field('id', required=True, location='path', schema=coreschema.String()), coreapi.Field('c', required=True, location='form', schema=coreschema.String(title='C')), coreapi.Field('d', required=False, location='form', schema=coreschema.String(title='D')), ]), 'custom_action_with_list_fields': coreapi.Link( url='/example/{id}/custom_action_with_list_fields/', action='post', encoding='application/json', description= 'A custom action using both list field and list serializer in the serializer.', fields=[ coreapi.Field('id', required=True, location='path', schema=coreschema.String()), coreapi.Field('a', required=True, location='form', schema=coreschema.Array( title='A', items=coreschema.Integer())), coreapi.Field('b', required=True, location='form', schema=coreschema.Array( title='B', items=coreschema.String())), ]), 'custom_list_action': coreapi.Link(url='/example/custom_list_action/', action='get'), 'custom_list_action_multiple_methods': { 'read': coreapi.Link( url='/example/custom_list_action_multiple_methods/', action='get'), 'create': coreapi.Link( url='/example/custom_list_action_multiple_methods/', action='post') }, 'update': coreapi.Link( url='/example/{id}/', action='put', encoding='application/json', fields=[ coreapi.Field('id', required=True, location='path', schema=coreschema.String()), coreapi.Field( 'a', required=True, location='form', schema=coreschema.String( title='A', description=('A field description'))), coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')), coreapi.Field( 'ordering', required=False, location='query', schema=coreschema.String( title='Ordering', description= 'Which field to use when ordering the results.' )) ]), 'partial_update': coreapi.Link( url='/example/{id}/', action='patch', encoding='application/json', fields=[ coreapi.Field('id', required=True, location='path', schema=coreschema.String()), coreapi.Field( 'a', required=False, location='form', schema=coreschema.String( title='A', description='A field description')), coreapi.Field('b', required=False, location='form', schema=coreschema.String(title='B')), coreapi.Field( 'ordering', required=False, location='query', schema=coreschema.String( title='Ordering', description= 'Which field to use when ordering the results.' )) ]), 'delete': coreapi.Link( url='/example/{id}/', action='delete', fields=[ coreapi.Field('id', required=True, location='path', schema=coreschema.String()), coreapi.Field( 'ordering', required=False, location='query', schema=coreschema.String( title='Ordering', description= 'Which field to use when ordering the results.' )) ]) } }) assert response.data == expected
class SubmitView(APIView): """ 提交 """ permission_classes = (IsAuthenticated,) schema = AutoSchema(manual_fields=[ coreapi.Field(name='problem', required=True, location='form', schema=coreschema.Integer(title='problem', description='要提交的题目ID')), coreapi.Field(name='submit_files', required=True, location='form', schema=coreschema.Array(title='submit_files', items=coreschema.Integer, description='要提交的文件(代码等)')), ]) def post(self, request, *args): # Fix bug: must check permission first self.check_permissions(request) # put the user segment in, ref: BaseSerializer docstring # Fix bug: AttributeError: This QueryDict instance is immutable # ref: https://stackoverflow.com/questions/44717442/this-querydict-instance-is-immutable data = request.data.copy() data['user'] = request.user.id serializer = SubmissionSerializer(data=data) # print(request.data) # print(serializer.initial_data) try: serializer.is_valid(True) # (Optional) Checking for deadline time ddl = Problem.objects.filter(id=data['problem'])[0].deadline_time if ddl is not None and ddl < django.utils.timezone.now(): # Whoops, you dare submitting it over ddl! return Response("You've submitted it after deadline! {}".format(str(ddl)), status.HTTP_400_BAD_REQUEST) subm = serializer.save() # Instantiate judge task for all testcases # Get all test cases related to this problem prob_id = serializer.data['problem'] subm_id = subm.id # print("{} {}".format(prob_id, subm_id)) prob = Problem.objects.filter(id=prob_id).first() if prob == None: return Response('No such problem', status.HTTP_404_NOT_FOUND) for case in prob.get_testcases(): # Create a new SubmissionResult structure subm_res = SubmissionResult.objects.create( status='PENDING', submission=subm, testcase=case, grade=0, log="", app_data="", possible_failure='NA' ) do_judge_task.delay(subm_id, case.id, subm_res.id) #do_judge_task(serializer.data['id'], serializer.data['']) return Response(serializer._data, status.HTTP_201_CREATED) except Exception as e: return Response(str(e), status.HTTP_500_INTERNAL_SERVER_ERROR)
class BCTenYrView(APIView, ModelWebServiceMixin): """ Ten year breast cancer risks calculation Web-Service """ renderer_classes = ( JSONRenderer, TemplateHTMLRenderer, ) serializer_class = BCTenYrSerializer authentication_classes = ( SessionAuthentication, BasicAuthentication, TokenAuthentication, ) permission_classes = (IsAuthenticated, ) throttle_classes = (BurstRateThrottle, SustainedRateThrottle, EndUserIDRateThrottle) model = settings.BC_MODEL if coreapi is not None and coreschema is not None: fields = ModelWebServiceMixin.get_fields(model) fields.insert( 0, coreapi.Field( name="tenyr_ages", required=True, location='form', schema=coreschema.Array( title="tenyr_ages", description='List of ages to calculate the 10-year risks', min_items=1, unique_items=True))) schema = ManualSchema(fields=fields, encoding="application/json", description=""" Ten year breast cancer risks calculations as per those given for the ages 40-49 (https://canrisk.atlassian.net/wiki/x/NwDCAg). The web-service takes a list of ages to calculate the 10-year risks for, e.g. [25, 26, 27, 28, 29] or [29]. """) # @profile("profile_bws.profile") def post(self, request): serializer = self.serializer_class(data=request.data) if serializer.is_valid(raise_exception=True): validated_data = serializer.validated_data pf = PedigreeFile(validated_data.get('pedigree_data')) model_settings = settings.BC_MODEL params = ModelParams.factory(validated_data, model_settings) tenyr_ages = re.sub("[\[\]]", "", validated_data.get('tenyr_ages')) tenyr_ages = [int(item.strip()) for item in tenyr_ages.split(',')] output = { "timestamp": datetime.datetime.now(), "mutation_frequency": { params.population: params.mutation_frequency }, "mutation_sensitivity": params.mutation_sensitivity, "cancer_incidence_rates": params.cancer_rates, "pedigree_result": [] } prs = validated_data.get('prs', None) if prs is not None: prs = Prs(prs.get('alpha'), prs.get('zscore')) try: warnings = PedigreeFile.validate(pf.pedigrees) if len(warnings) > 0: output['warnings'] = warnings except ValidationError as e: logger.error(e) return JsonResponse(e.detail, content_type="application/json", status=status.HTTP_400_BAD_REQUEST) # note limit username string length used here to avoid paths too long for model code cwd = tempfile.mkdtemp(prefix=str(request.user)[:20] + "_", dir=settings.CWD_DIR) try: for pedi in pf.pedigrees: risk_factor_code = 0 this_params = deepcopy(params) # check if Ashkenazi Jewish status set & correct mutation frequencies if pedi.is_ashkn() and not settings.REGEX_ASHKN.match( params.population): msg = 'mutation frequencies set to Ashkenazi Jewish population values ' \ 'for family ('+pedi.famid+') as a family member has Ashkenazi Jewish status.' logger.debug( 'mutation frequencies set to Ashkenazi Jewish population values' ) if 'warnings' in output: output['warnings'].append(msg) else: output['warnings'] = [msg] this_params.isashk = True this_params.population = 'Ashkenazi' this_params.mutation_frequency = model_settings[ 'MUTATION_FREQUENCIES']['Ashkenazi'] if isinstance(pedi, CanRiskPedigree): # for canrisk format files check if risk factors and/or prs set in the header mname = model_settings['NAME'] risk_factor_code = pedi.get_rfcode(mname) if prs is None or len(pf.pedigrees) > 1: prs = pedi.get_prs(mname) this_hgt = (pedi.hgt if hasattr(pedi, 'hgt') else -1) calcs = Predictions(pedi, model_params=this_params, risk_factor_code=risk_factor_code, hgt=this_hgt, prs=prs, run_risks=False, cwd=cwd, request=request, model_settings=model_settings) calcs.niceness = Predictions._get_niceness(calcs.pedi) calcs.ten_yr_cancer_risk = [] for tenyr in tenyr_ages: ten_yr_risk = RangeRisk(calcs, int(tenyr), int(tenyr + 10), "10 YR RANGE").get_risk() if ten_yr_risk is not None: calcs.ten_yr_cancer_risk.append(ten_yr_risk[0]) # Add input parameters and calculated results as attributes to 'this_pedigree' this_pedigree = {} this_pedigree["family_id"] = pedi.famid this_pedigree["proband_id"] = pedi.get_target().pid this_pedigree["risk_factors"] = self.get_risk_factors( model_settings, risk_factor_code) this_pedigree["risk_factors"][_( 'Height (cm)')] = this_hgt if this_hgt != -1 else "-" if prs is not None: this_pedigree["prs"] = { 'alpha': prs.alpha, 'zscore': prs.zscore } this_pedigree["mutation_frequency"] = { this_params.population: this_params.mutation_frequency } self.add_attr("version", output, calcs, output) self.add_attr("ten_yr_cancer_risk", this_pedigree, calcs, output) output["pedigree_result"].append(this_pedigree) except ValidationError as e: logger.error(e) return JsonResponse(e.detail, content_type="application/json", status=status.HTTP_400_BAD_REQUEST, safe=False) finally: shutil.rmtree(cwd) # print("BCTenYr :: "+cwd) output_serialiser = OutputSerializer(output) return Response(output_serialiser.data, template_name='result_tab_gp.html') return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def test_schema_for_regular_views(self): """ Ensure that AutoField many to many fields are output as Integer. """ generator = SchemaGenerator(title='Example API', patterns=self.patterns) schema = generator.get_schema() expected = coreapi.Document( url='', title='Example API', content={ 'example': { 'create': coreapi.Link( url='/example/', action='post', encoding='application/json', fields=[ coreapi.Field('name', required=True, location='form', schema=coreschema.String(title='Name')), coreapi.Field('targets', required=True, location='form', schema=coreschema.Array(title='Targets', items=coreschema.Integer())), ] ) } } ) assert schema == expected