Power Query - Multiple request for different parameter values - rest
I'm novice in using Power Query for REST API and have a Power BI report to amend to bring in additional data. I have developed a query and custom function to return the data, which works fine for a single STATUS request parameter value. This is in the following statement;
Source = Json.Document(Web.Contents("https://api.clockify.me/api/v1" & "/workspaces/"& Workspace&"/approval-requests?page="&Page&"&page-size="&PageSize&"&status="&Status,
[Headers=[#"X-API-Key"=#"X-API-Key",
#"Content-Type"="JSON"]]
)
),
However I need to return values for all four status codes (APPROVED,PENDING,REJECTED,APPROVAL_WITHDRAWN") in my query .
Clockify advise multiple parameter values are not supported for this API and that I would need to pull a request for each status separately. Unfortunately I'm at a loss how to restructure my queries to do this, so would be really grateful for any advice.
Thanks
Full query and custom function shown below;
let
Source = "",
Custom1 = List.Numbers(1 as number, 50 as number) as list,
#"Converted to Table" = Table.FromList(Custom1, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Changed Type" = Table.TransformColumnTypes(#"Converted to Table",{{"Column1", type text}}),
#"Invoked Custom Function" = Table.AddColumn(#"Changed Type", "Data", each get_page_fx([Column1])),
#"Removed Errors" = Table.RemoveRowsWithErrors(#"Invoked Custom Function", {"Column1"}),
#"Removed Columns" = Table.RemoveColumns(#"Removed Errors",{"Column1"}),
#"Removed Errors1" = Table.RemoveRowsWithErrors(#"Removed Columns", {"Data"}),
#"Expanded Data" = Table.ExpandTableColumn(#"Removed Errors1", "Data", {"id", "workspaceId", "dateRange.start", "dateRange.end", "owner.userId", "owner.userName", "owner.timezone", "owner.startOfWeek", "status.state", "status.updatedBy", "status.updatedByUserName", "status.updatedAt", "status.note"}, {"Data.id", "Data.workspaceId", "Data.dateRange.start", "Data.dateRange.end", "Data.owner.userId", "Data.owner.userName", "Data.owner.timezone", "Data.owner.startOfWeek", "Data.status.state", "Data.status.updatedBy", "Data.status.updatedByUserName", "Data.status.updatedAt", "Data.status.note"})
in
#"Expanded Data
"
(Page as text) =>
let
Source = Json.Document(
Web.Contents("https://api.clockify.me/api/v1" & "/workspaces/"& Workspace&"/approval-requests?page="&Page&"&page-size="&PageSize&"&status="&Status,
[Headers=[#"X-API-Key"=#"X-API-Key",
#"Content-Type"="JSON"]]
)
),
#"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"id", "workspaceId", "dateRange", "owner", "status"}, {"id", "workspaceId", "dateRange", "owner", "status"}),
#"Expanded dateRange" = Table.ExpandRecordColumn(#"Expanded Column1", "dateRange", {"start", "end"}, {"dateRange.start", "dateRange.end"}),
#"Expanded owner" = Table.ExpandRecordColumn(#"Expanded dateRange", "owner", {"userId", "userName", "timezone", "startOfWeek"}, {"owner.userId", "owner.userName", "owner.timezone", "owner.startOfWeek"}),
#"Expanded status" = Table.ExpandRecordColumn(#"Expanded owner", "status", {"state", "updatedBy", "updatedByUserName", "updatedAt", "note"}, {"status.state", "status.updatedBy", "status.updatedByUserName", "status.updatedAt", "status.note"}),
#"Changed Type" = Table.TransformColumnTypes(#"Expanded status",{{"id", type text}, {"workspaceId", type text}, {"dateRange.start", type datetime}, {"dateRange.end", type datetime}, {"owner.userId", type text}, {"owner.userName", type text}, {"owner.timezone", type text}, {"owner.startOfWeek", type text}, {"status.state", type text}, {"status.updatedBy", type text}, {"status.updatedByUserName", type text}, {"status.updatedAt", type datetime}, {"status.note", type any}})
in
#"Changed Type"
hard code status into the function. Duplicate that function 3 more times, with different status in each and different query names. In the main query, you add a column for get_page_fx([Column1])). Add three more columns, one by one, each calling one of the three new functions: get_page_fx2([Column1])) get_page_fx3([Column1])) and get_page_fx4([Column1])). Thats all the data. If you want, you can them combine the columns with append
Related
Postgresql - querying jsonb throws a syntax error
I have a table that has a column data of jsonb type. create table event ( id bigserial primary key, created_at timestamp with time zone default now() not null, type text not null, created_by text, data jsonb, event_time timestamp with time zone default now() not null ); In that field I am saving a json object that looks like this: { "comment": "Changed by recipient", "source": "Recipient page" } I would like to query values in that table by the value of the comment property of the data json object. Something like this in based by examples [here][1]: select * from event where type = 'pickup-data-changed' and data -> 'comment' = 'Changed by recipient' If I query like that I get an invalid token error: [22P02] ERROR: invalid input syntax for type json Detail: Token "Changed" is invalid. Position: 104 What am I doing wrong here? If I do it as a double arrow like suggested in the comments: select * from event where type = 'pickup-data-changed' and data ->-> 'comment' = 'Changed by recipient' I get an error: [42883] ERROR: operator does not exist: jsonb ->-> unknown Hint: No operator matches the given name and argument types. You might need to add explicit type casts. How can I make this query work? [1]: https://kb.objectrocket.com/postgresql/how-to-query-a-postgres-jsonb-column-1433
I get an invalid token error. What am I doing wrong here? data -> 'comment' returns a value of type jsonb, so the right hand side of the comparison 'Changed by recipient' is parsed as JSON as well - and it's invalid JSON. To create a JSON string value to compare against, you'd need to write … data -> 'comment' = '"Changed by recipient"' If I do it as a double arrow like suggested in the comments, data ->-> 'comment' The comments suggested … data ->> 'comment' = 'Changed by recipient' not ->->.
alternatives: select * from event where type = 'pickup-data-changed' and data -> 'comment' = '"Changed by recipient"'::jsonb; or select * from event where type = 'pickup-data-changed' and data['comment'] = '"Changed by recipient"'::jsonb;
Get text between two annotated tags in ruta
How to get data present between two annotated texts? Sample input: Seller Name FirstAvenue Mortgage, TN 12230 Contact Name John Code : BLOCK(sellerName) Line{CONTAINS(SellerNameKeyword)} { c:ANY+{-PARTOF(SellerNameKeyword), -PARTOF(SellerName)-> CREATE(SellerName, "label"="Seller Name", "value"=c.ct)} ContactNameKeyword; } This code is not giving any output for SellerName annotation Expected Output : FirstAvenue Mortgage, TN 12230 What changes if input is spread across two lines ? Sample input: Seller Name FirstAvenue Mortgage, Contact Name John TN 12230 Contact Title Supervisor Code for above mentioned use case: TYPESYSTEM utils.PlainTextTypeSystem; ENGINE utils.PlainTextAnnotator; DECLARE Keyword (STRING label); DECLARE Entry(Keyword keyword); DECLARE Keyword SellerNameKeyword, SellerNameContextBlocker, ContactNameKeyword; EXEC(PlainTextAnnotator, {Line,Paragraph}); ADDRETAINTYPE(WS); Line{->TRIM(WS)}; Paragraph{->TRIM(WS)}; REMOVERETAINTYPE(WS); "Seller Name" -> SellerNameKeyword ( "label" = "Seller Name"); "Contact Title" -> SellerNameContextBlocker("label" = "Seller Name Context Blocker"); "Contact Name" -> ContactNameKeyword("label"= "Contact Name"); DECLARE Entity (STRING label, STRING value); DECLARE Entity ContactName, SellerName; BLOCK(line1) Line{CONTAINS(ContactNameKeyword)} { ContactNameKeyword c:#{-PARTOF(ContactName)-> CREATE(ContactName,"label"="Contact Name", "value"=c.ct)}; } SellerNameKeyword c:#{-PARTOF(ContactNameKeyword),-PARTOF(SellerNameContextBlocker),-PARTOF(ContactName) -> CREATE(SellerName,"label"="Seller Name", "value"=c.ct)} SellerNameContextBlocker; Output : FirstAvenue Mortgage, Contact Name John TN 12230 Expected Output : FirstAvenue Mortgage, TN 12230 Please suggest required changes and what I have missed ?
Since the information you want to annotate is not sequential in text ("Contact Name John" comes in between) you cannot represent the desired output in CAS as the covered text of a single annotation. However, in your case, you might want to join together the text of interest in a feature of the output annotation. For example: DECLARE SellerNameKeyword, ContactNameKeyword, ContactTitleKeyword; DECLARE SellerName (STRING value); "Seller Name" -> SellerNameKeyword; "Contact Name" -> ContactNameKeyword; "Contact Title" -> ContactTitleKeyword; ADDRETAINTYPE(BREAK); SellerNameKeyword ANY[0,5]{-PARTOF(ContactNameKeyword), -PARTOF(COMMA) -> s1:CREATE(SellerName)} COMMA? ContactNameKeyword ANY[0,5]{-PARTOF(BREAK)} BREAK? ANY[0,10]{-PARTOF(ContactTitleKeyword) -> s2:CREATE(NameId), s1.value=""+s1.ct+s2.ct} ContactTitleKeyword; ADDRETAINTYPE(BREAK); The output of this rules will return an annotation SellerName on "FirstAvenue Mortgage" with feature value containing the desired output "FirstAvenue Mortgage TN 12230". Mind that this is not a general solution but rather an example how it can be done in the give case.
Null field validation in Django forms
I am trying to filter a null field and validate it in forms.py But i get below error : Cannot assign None: "TeacherAttendance.teacher" does not allow null values. But i am doing validation in the form as below for teacher field. It should generate "Please choose teacher" validation warning. But it is not doing. It should validate the null value for teacher and go back to form with a validation warning if i dont choose a teacher from teacher field. class TeacherAttendanceForm(forms.ModelForm): class Meta: model = TeacherAttendance fields = ('time', 'attendance', 'teacher','dailynote','writer',) exclude = ['uuid', 'notedate',] widgets = { 'attendance': forms.RadioSelect(renderer=HorizontalRadioRenderer), 'dailynote': forms.Textarea(attrs={'rows': 10}), 'writer': forms.Textarea(attrs={'rows': 1}), 'uuid': forms.HiddenInput(), 'semester': forms.HiddenInput(), } def clean(self): if str(self.cleaned_data['time']) == "-----------": raise forms.ValidationError('Please choose time.') if self.cleaned_data['dailynote'] == "": raise forms.ValidationError('Please enter note.') if not self.cleaned_data['teacher']: raise forms.ValidationError('Please choose teacher .') My model is below and teacher field is a dropdown filed that shows all teacher. class TeacherAttendance(BaseModel): teacher = models.ForeignKey(Staff, blank=True, verbose_name=_("Choose Teacher")) attendance = models.CharField(choices=TEACHER_ATTENDANCE, default="YOK", max_length=20, verbose_name=_("Attendance")) time = models.CharField(choices=TIME, default="-------------", max_length=20, verbose_name=_("Time")) dailynote = models.TextField(null=True, blank=True, verbose_name=_("Add Note")) notedate = models.DateField(auto_now_add=True, db_index=True, verbose_name=_("Date")) writer = models.TextField(null=True, blank=True, verbose_name=_("Writer")) class Meta: unique_together = ("teacher", "attendance", "notedate") index_together = [["teacher", "notedate", ], ] def __unicode__(self): return "%s / %s / %d " % (self.teacher, self.notedate, self.attendance)
I solved the question by changing below field in model : teacher = models.ForeignKey(Staff, blank=True, verbose_name=_("Choose Teacher")) to : teacher = models.ForeignKey(Staff, blank=True, null=True, verbose_name=_("Choose Teacher")) by adding "null=True" to the field. Probably it was first looking at the model field before doing form validation.
Swagger on Scala, type uuid and long are undefined
I'm trying to implement swagger on my routes with akka-http 10.0.0 and swagger-akka-http 0.8.2. It works well but query parameter with type : UUID and Long are considered as undefined. Should I use format? How to use it? Here is one of my route : #GET #Path("/{publisher_id}/{app_id}") #ApiOperation( value = "get a app Installation stat for an app ID", notes = "Returns a session based on ID", httpMethod = "GET" ) #ApiImplicitParams(Array( new ApiImplicitParam(name = "app_id", value = "ID of app that needs to be fetched, format com.totot.plop ", required = true, dataType = "string", paramType = "path"), new ApiImplicitParam(name = "publisher_id", value = "publisher id : publisher_id ", required = true, dataType = "UUID?", paramType = "path"), new ApiImplicitParam(name = "date_start", value = "Timestamp start date ", required = true, dataType = "LONG???" , paramType = "query"), new ApiImplicitParam(name = "date_end", value = "Timestamp end date", required = true, dataType = "LONG???", paramType = "query"), new ApiImplicitParam(name = "access_token", value = "session token of the user ", required = true, dataType = "UUID????", paramType = "query") )) #ApiResponses(Array( new ApiResponse(code = 404, message = "App not found"), new ApiResponse(code = 400, message = "Invalid ID supplied"), new ApiResponse(code = 401, message = "access token invalid") ))
For Long, use #ApiImplicitParam(... dataType="long" ...). The swagger json that gets generated for the parameter: { "name" : "name", "in" : "query", "description" : "param desc", "required" : true/false, "type" : "int", "format" : "int64" } https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X has such an example param. For params of type java.util.UUID, there is no special processing in swagger.io code for UUIDs that I know of. So I would recommend dataType="string". As a general pointer, #ApiImplicitParam dataType is documented as: /** * The data type of the parameter. * <p> * This can be the class name or a primitive. */ The primitive values seem to be the java primitive type names, eg int, long, etc. string is also supported.
First of all, you can specify a class as it said in the document: The dataType can be either a primitive or a class name. https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X#apiimplicitparam-apiimplicitparams By class name, it means you have to include the full class name which is "java.util.UUID", or {UUID.class} as mentioned in the document.
How to get conversion completions by date
I am trying get a total from completions by date, but conversions don't have dimension date, actually the query is https://www.googleapis.com/analytics/v3/data/ga?ids=ga%xxxxxx&start-date=2013-10-20&end-date=2013-11-20&metrics=ga%3AgoalStartsAll%2Cga%3AgoalCompletionsAll%2Cga%3AgoalValueAll%2Cga%3AgoalValuePerSession%2Cga%3AgoalConversionRateAll&dimensions=ga%3AgoalCompletionLocation&max-results=10
Did you try use Query Builder? https://ga-dev-tools.appspot.com/query-explorer/ You can select ga: date and ga: goalCompletionsAll https://ga-dev-tools.appspot.com/query-explorer/?start-date=30daysAgo&end-date=yesterday&metrics=ga%3AgoalCompletionsAll&dimensions=ga%3Adate
#get report data query.list <- Init(start.date = "XXXXXX", end.date = "XXXXXX", dimensions = "ga:date", metrics = "ga:goalXXCompletions", table.id = "ga:XXXXX")