-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Log Analytics data plane SDK #2557
Conversation
Can one of the admins verify this patch? |
Codecov Report
@@ Coverage Diff @@
## master #2557 +/- ##
==========================================
+ Coverage 56.71% 56.74% +0.03%
==========================================
Files 7647 7666 +19
Lines 158352 158544 +192
==========================================
+ Hits 89803 89963 +160
- Misses 68549 68581 +32
Continue to review full report at Codecov.
|
Hi @alexeldeib ! Most important here is that Python has no history to follow, so the mgmt package was release using the correct This has to be the same here, but overriding package name and title, like I did here: Also, it seems to be not ARM, so the correct dependency will be "msrest" and not "msrestazure": To answer your questions now:
Thanks! |
Note, the |
PyCon sounds exciting! Hope it was fun 👍 I missed the management packages -- I'll change the naming to match. I'll also fix the dependency in setup.py. On the point about workspace ID, coincidentally I have a PR out with that change 😄 I also updated the readme there for generation which (of course) produced another PR. To the last bit about the string parameter: this is the field in the swagger. I saw models all have code like this: _attribute_map = {
'name': {'key': 'name', 'type': 'str'},
'columns': {'key': 'columns', 'type': '[Column]'},
'rows': {'key': 'rows', 'type': '[[str]]'},
} I had a chance to test this out and I see see that the python client does respect the string types in the swagger, converting the JSON type, e.g.:
For context, here's the JSON returned from the HTTP call (note the boolean and raw number values returned, converted to strings): [ "OpsManager", "2018-04-22T08:40:09.77Z", "00000000-0000-0000-0000-000000000001", "40.83.215.18", "Direct Agent", "Windows", "", "10", "0", "8.0.11081.0", "Direct", false, -121.83, # HERE 37.32, "United States", "microsoft.compute", "Azure", "\"security\", \"serviceMap\", \"securityCenterFree\"", "Heartbeat" ] Answering my own question -- the client will respect whatever is in the swagger. My follow up, then: we have the information for column types. Could I do some custom modeling to convert/cast the underlying values so they look right from the service perspective? For example, a value returned as a number in JSON will come back as a string but I would convert it back using the column.type field to determine type. We are returning rows from DB query, but due to restriction in swagger/autorest we can't model the value as multiple primitive types (yet!). So we ended up with string. I'm trying to work around that at the SDK level to provide a better experience. Curious what you think. |
@alexeldeib Yes, we can do custom serialization/deserialization. But in this case, it seems I just have to not try to hard and expose what was on the JSON right? Could you confirm this is all basic types? For instance, there is not date in ISO8601 string your expect to be exposed as If this is just exposing bool/str/int/float, I can probably add an internal option in my runtime to say "Don't try serialize/deserialize". Example: _attribute_map = {
'name': {'key': 'name', 'type': 'str'},
'columns': {'key': 'columns', 'type': '[Column]'},
'rows': {'key': 'rows', 'type': '[[str]]', 'transform': False},
} Thoughts? |
Your proposal is the ideal. We really want to expose what the API brings back, because it "knows better" than the swagger. There are some ISO8601 format strings, but we are modeling these as strings in swagger anyway (due to format limitations), so this shouldn't present a problem python-side. BTW -- I'm waiting to move forward here until the swagger-side cleanup from the above PR is complete. It includes the workspace_id => method parameter change, as well as some more general housekeeping. |
@alexeldeib Swagger (at least Autorest, maybe there is subtle difference between Autorest and Swagger here) supports ISO8601, and we have automatic transformer for that. You should need to use format "date-time" and on the SDK side you receive a date object ( What I saw sometimes, in that C# serializes by default 7 level microseconds precision, which is not handled by all languages. It's why Microsoft OneApi guideline asks explicitly for 3 level precision and not more, to accommodate all languages. There is some Swagger that are designed as string because of that, because it's not a valid ISO8601 string for Microsoft OneApi. If your server does that, yes you have to use string :/ |
Side bar -- for the results, we're actually modeled just as string in swagger. This was the swagger/autorest limitation -- giving this a variety of type possibilities. So we landed on just making all the row results string in swagger. The comments about timestamps apply to parameters, but not results. So, what we found with C# was actually that date time worked fine, but that we didn't have good support for ISO8601 intervals, which we use (e.g. query timespan). Do you happen to know if that would work well in Python? A cursory search tells me the standard datetime objects can do durations but not intervals. I haven't played around this with the SDK, which would answer my question...but I figured you would know best 😄 If it ends up that the intervals/durations work well, I'll add a transform in the swagger to include format: duration/format: interval (or the appropriate keywords, per your guidance) to the swaggers for client generation. I think for ISO8601 interval in particular we didn't find a good "format" keyword to feed autorest to get the desired result. |
@alexeldeib You mean intervals like |
@lmazuel The corresponding updates were merged in the specification repo, I regenerated and added a basic test case for usage. Functionally, from my end this is good to go. Let me know if you still see anything that wasn't covered. One thing I noticed with the autorest configuration -- there is some weird behavior here.
Not sure what autorest is doing here, but it doesn't seem to respect the "title" override. For the time being, I manually generated the SDK with the global title "LogAnalyticsDataPlane" rather than "OperationalInsightsDataPlane". This is the diff of the readme I used against master. This probably means the AutoPR's will be messed up, but I assume the autorest overrides won't work in other languages either. That may take some deeper investigation to resolve. |
You're 100% right @alexeldeib we discovered that with @fearthecowboy recently. There is no way to make the override to work inside the Python section, it has to be moved into the global section. |
Here's the readme diff. The generated code is identical except for the description [diff] So I see three options:
Personally, I'd prefer to avoid option 3 -- it doesn't make sense to block on that single line description. I've gone with the second option for right now. If you think that's okay, I'll merge the corresponding readme diff into the spec repo. Or if you prefer the first option, I can make the change here and merge the corresponding readme change as well. |
I like your diff, just want @fearthecowboy feedback on using |
Sounds good, no problem to wait. I didn't know about this either 😄 I found it when I went to generate NodeJS library, someone did the same for Log Analytics/Operational Insights already on the resource manager side: https://github.com/Azure/azure-rest-api-specs/blob/master/specification/operationalinsights/resource-manager/readme.nodejs.md |
@fearthecowboy any comment on this? |
I have no idea where it does look like it's in the different generators, so you should be ok. |
Is there a preferred way to do the same transform otherwise? Definitely happy to avoid using a hack, if there is another approach. |
@lmazuel any thoughts on this? I looked at this in the generators and i'm fine with using it. |
@alexeldeib I'm a little confused about the relation between this PR and #2767? Should not one of them being closed? |
No, these are distinct. I'll follow up offline with some additional detail. |
Bump? 😊 @lmazuel |
Looks good to me! Thanks @lmazuel |
Great! Let's release this guy :) |
Hi all! I'm introducing a new client to query Log Analytics (the operational insights resource provider in Azure). Tested out the SDK manually and it looks great, had a couple questions though!
I saw the testing using stubbed management clients, is there an equivalent for data plane clients? or can I implement some testing using that framework and custom endpoints? I looked to KeyVault often as an example of a service slightly parallel our own -- custom endpoint, auth resource, etc, but they don't have tests? (after thinking about this some more, I misread the original code I think -- looks like I just need to new up a client).
Due to swagger limitations we have one field of our response type that's modeled as a string (it's the type of the row value in the tables) but on the wire can actually be pretty much any primitive type: string, int, null, float/double, some datetime formats. In C# we are somewhat forced to deal with the strings but we have type information returned by the API to type them appropriately. I haven't tested this bit too closely, but will the python client respect the wire format, or actually use the attribute mappings to cast things to string?
rest-api-specs spec