help with event stream
AnsweredI don't fully understand how to query events using the API. My goal is for me to specify a start and end date and only retrieve events for that time period. According to the documentation, I can only use created_before and created_after if I don't include a stream position. So, my initial request to the API includes a created_before and a created_after. However, the amount of events that are returned are larger than the limit... so my next request has to include a stream position... At that point... how do I stop getting results up to the date I want? If i include created_before, it will be ignored because I have to include the stream position?
I just don't get it 😞
-
Hi,
I believe when you get the first result like this:
chunk_size": 1, "next_stream_position": ***number removed for privacy***9819, "entries": [ ........
For the next call, you would still specify limit but use the stream position value to be the value of "next_stream_position". so, your stream position will be "***number removed for privacy***9819" for the next call. And you should do while loop or any loop until the next_stream_position gets to current.
let me know if this makes sense.
thanks,
Bibek
-
Here's some code:
static void Main(string[] args) { Task t = MainAsync(); t.Wait(); Console.WriteLine("Done..."); Console.ReadKey(); } static async Task MainAsync() { var privateKey = File.ReadAllText(PRIVATE_KEY_FILE); var boxConfig = new BoxConfig(CLIENT_ID, CLIENT_SECRET, ENTERPRISE_ID, privateKey, JWT_PRIVATE_KEY_PASSWORD, JWT_PUBLIC_KEY_ID); var boxJWT = new BoxJWTAuth(boxConfig); var adminToken = boxJWT.AdminToken(); var adminClient = boxJWT.AdminClient(adminToken); DateTime createdAfter = DateTime.Parse("2016-12-01T01:00:00-7:00"); // 2014-05-17T13:35:01-07:00 DateTime createdBefore = DateTime.Parse("2016-12-01T01:05:00-7:00"); string streamPosition = null; await loadEvents(adminClient, createdAfter, createdBefore, streamPosition); } static async Task loadEvents(BoxClient adminClient, DateTime createdAfter, DateTime createdBefore, string streamPosition) { Console.WriteLine("stream position: " + streamPosition); BoxEventCollection events = await adminClient.EventsManager.EnterpriseEventsAsync( 500, streamPosition, null, createdAfter, createdBefore); events.Entries.ForEach(i => { // get your events }); string nextStreamPosition = events.NextStreamPosition; if ((null != nextStreamPosition) && (nextStreamPosition != streamPosition)) { BoxEnterpriseEvent be = events.Entries.Last(); Console.WriteLine(be.CreatedAt); await loadEvents(adminClient, createdAfter, createdBefore, nextStreamPosition); } }
And here's the output:
stream position:
12/1/2016 4:01:10 PM
stream position: 1152922985214917947
12/1/2016 4:02:16 PM
stream position: 1152922985214983518
12/1/2016 4:03:09 PM
stream position: 1152922985215036862
12/1/2016 4:04:16 PM
stream position: 1152922985215103558
12/1/2016 4:04:59 PM
stream position: 1152922985215146913
Done... -
Thank you. This is pretty much what I eventually did... I think it is working. (My code is in powershell.. but looks very similar).
However, what is confusing to me is that once you start using stream position, you can no longer user the created before and created after dates. So if you want to get the events for a time period, wouldn't you also need to make sure that you stop at the "created before" date?
Here's what I ended up with (that definitely needs cleaned up) :
function Get-BoxAdminLog($token,$eventtype,$createdafter, $createdbefore, $limit=500){ $head = @{} $head.Add("Authorization","Bearer $token") if($createdafter -and $createdbefore){ $uri = "https://api.box.com/2.0/events?stream_type=admin_logs&event_type=$eventtype&created_after=$createdafter&created_before=$createdbefore&limit=$limit" } elseif($createdafter){ $uri = "https://api.box.com/2.0/events?stream_type=admin_logs&event_type=$eventtype&created_after=$createdafter&limit=$limit" } elseif($createdbefore){ $uri = "https://api.box.com/2.0/events?stream_type=admin_logs&event_type=$eventtype&created_before=$createdbefore&limit=$limit" } else{ return "Please provide createdbefore, createdafter, or both" } $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $head -ContentType "application/x-www-form-urlencoded" if($return.next_stream_position -eq 0){ #get-date | out-file c:\temp\test.txt return $return.entries } else{ $streampos = $return.next_stream_position $items = $return.entries while($return.next_stream_position -ne 0){ $uri = "https://api.box.com/2.0/events?stream_type=admin_logs&event_type=$eventtype&stream_position=$streampos&limit=$limit" $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $head -ContentType "application/x-www-form-urlencoded" if($return.next_stream_position -eq $streampos){ break } $items += $return.entries $streampos = $return.next_stream_position if($createdbefore){ if($return.entries[-1].created_at -gt $createdbefore){ break } } } return $items } }
-
I believe it uses all 3. When it first starts, it has no stream position and only createdAfter & createdBefore. Then after the first loop, you'll get a stream_position but it will stop once it reaches createdBefore.
I changed the code to output all 3 variables on the above test...
stream position: createdAfter: 12/1/2016 8:00:00 AM createdBefore: 12/1/2016 8:05:00 AM ------------------------------------- 12/1/2016 4:01:10 PM stream position: 1152922985214917947 createdAfter: 12/1/2016 8:00:00 AM createdBefore: 12/1/2016 8:05:00 AM ------------------------------------- 12/1/2016 4:02:16 PM stream position: 1152922985214983518 createdAfter: 12/1/2016 8:00:00 AM createdBefore: 12/1/2016 8:05:00 AM ------------------------------------- 12/1/2016 4:03:09 PM stream position: 1152922985215036862 createdAfter: 12/1/2016 8:00:00 AM createdBefore: 12/1/2016 8:05:00 AM ------------------------------------- 12/1/2016 4:04:16 PM stream position: 1152922985215103558 createdAfter: 12/1/2016 8:00:00 AM createdBefore: 12/1/2016 8:05:00 AM ------------------------------------- 12/1/2016 4:04:59 PM stream position: 1152922985215146913 createdAfter: 12/1/2016 8:00:00 AM createdBefore: 12/1/2016 8:05:00 AM ------------------------------------- Done...
-
Can you share the code? In the original code, createdAfter and createdBefore were variables that you defined... so I would expect that the output is just printing variables you defined and not data returned from the API call.
Also, the documentation specifically says:
Important Box responds to the created_before and created_after parameters only if the stream_position parameter is not included.
-
static async Task MainAsync() { var privateKey = File.ReadAllText(PRIVATE_KEY_FILE); var boxConfig = new BoxConfig(CLIENT_ID, CLIENT_SECRET, ENTERPRISE_ID, privateKey, JWT_PRIVATE_KEY_PASSWORD, JWT_PUBLIC_KEY_ID); var boxJWT = new BoxJWTAuth(boxConfig); var adminToken = boxJWT.AdminToken(); var adminClient = boxJWT.AdminClient(adminToken); DateTime createdAfter = DateTime.Parse("2016-12-01T01:00:00-7:00"); DateTime createdBefore = DateTime.Parse("2016-12-01T01:05:00-7:00"); string streamPosition = null; await loadEvents(adminClient, createdAfter, createdBefore, streamPosition); } static async Task loadEvents(BoxClient adminClient, DateTime createdAfter, DateTime createdBefore, string streamPosition) { Console.WriteLine("stream position: " + streamPosition); Console.WriteLine("createdAfter: " + createdAfter); Console.WriteLine("createdBefore: " + createdBefore); Console.WriteLine("-------------------------------------"); BoxEventCollection events = await adminClient.EventsManager.EnterpriseEventsAsync( 500, streamPosition, null, createdAfter, createdBefore); events.Entries.ForEach(i => { // get your events }); string nextStreamPosition = events.NextStreamPosition; if ((null != nextStreamPosition) && (nextStreamPosition != streamPosition)) { BoxEnterpriseEvent be = events.Entries.Last(); Console.WriteLine(be.CreatedAt); await loadEvents(adminClient, createdAfter, createdBefore, nextStreamPosition); } }
-
If your events actually stop at the "created_before" datetime... then the API call has to be using the created_before parameter still even though you are providing the stream_position... this goes opposite of what the documentation says.
Because... the only thing stopping your loop is if the steamposition returned is null or if the stream position returned is the same as the last call... right?
Please sign in to leave a comment.
Comments
9 comments