-
Notifications
You must be signed in to change notification settings - Fork 22
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
JSON schema #128
Comments
Not yet, it's generated directly from the internal metadata shared with the our parser at runtime. There are a couple of on-going tasks related to that targeting a more general proposal (includes JSON and Arrow dataframes) and the C++ port of the engine, besides what's listed in https://dss-extensions.org/dss_python/examples/JSON/#Future-expectations Note that there are initial type annotations in DSS-Python and in https://github.com/dss-extensions/dss_python/blob/0.14.4/dss/IObj.py (this file will be split and moved to a new module later). After #78 lands, we plan to add annotations in ODD.py too. For
There will be
We can add whatever flags users find useful here on DSS-Extensions. As long as a flag needs to be explicitly enabled through the API and we mark it a an extension (not supported in the official OpenDSS), it's fine.
We already can kinda do that, but a high-level end-user API is missing. Including that explicitly in an alternative format would be nice. |
Thanks for the detailed response. My highest priority in the short-term is the ability to programmatically interact with the OpenDSS data models without loading OpenDSS. This is great to hear: I do not have an immediate need for the LoadShapes_Set_Points example, but I suspect that there is user demand for this sort of thing - users may not ask for it or even know they need it. |
Sounds good, I'll ping you whenever I start working more directly on this too (I imagine in 1 to 3 weeks). A lot of properties have special handling in the parser. In general, we wouldn't need to handle those in JSON, etc. Let me know if you have any questions.
I think this is one point that we can call for community feedback and contributions more broadly since a lot of people have the same issues. So, the sooner we have something to iterate over, the better. If you haven't seen it yet, there's also this and a few other test files that contain some examples: https://github.com/dss-extensions/dss_python/blob/0.14.4/tests/test_obj.py If you want to check the current internal model: import json
from opendssdirect._utils import api_util
json.loads(api_util.ffi.string(api_util.lib.DSS_ExtractSchema(api_util.ffi.NULL))) Here's the output as a file: dss_capi_v0.13.4.json.zip |
I posted some code at daniel-thom@4286587. I wrote a quite hacky script (not posted) that converts the OpenDSS schema to Pydantic models. The file opendss_circuit.py shows how you can compile a circuit once, convert everything to Pydantic models, serialize and de-serialize to JSON, serialize to .dss text files, and then generally use the circuit without having to compile it with OpenDSS. This satisfies my immediate concern but it is really not a great solution and I wouldn’t open a PR for it. I encountered lots of tedious errors with strings because of differences in spellings and capitalization between what comes out of Just as a comment, I’ll mention that I have found Pydantic data models very useful for this sort of thing. It supports aliases for the cases of valid and invalid variable names. It also provides easy ways to add customizations where serializing and de-serializing to different formats. |
Thanks for the update!
Currently the data is exported as it's represented internally. For this example,
A lot of functions from the API, including the The initial plan, long ago, was to extract the internal model and generate the parser code externally. There are too many corner cases in the OpenDSS parser, so that's not perfect. We could still do this someday. I suspended working on that mostly because parsing code got a lot faster when I refactored it, even though I expected it to get slower. Some random notes:
@root_validator(pre=True)
def preprocess(cls, values):
"""Removes undesired fields."""
for field in ("DSSClass", "like"):
values.pop(field, None)
return values
If we can merge the idea of Pydantic models as in your example with IObj.py, it would probably both simplify the code and add useful features at the same time. We can add some basic validation (required and exclusive fields, at least) and most of the defaults. From what I gather, we could generate the code directly from a proper JSON-Schema too as seen in datamodel-code-generator, right? The typing situation in Python is non-ideal without something like Pydantic. Besides Pydantic, I guess we'll have to wait to see what happens in the long term regarding the likes of MyPy, LPython and Spy. |
Absolutely. That’s why I started this thread with the question about JSON schema. This question remains: What is the best way to get the formal schema? I started down the path of |
Let me play with it a bit first. I think it's easy enough to generate a JSON schema for most classes/properties instead of this custom JSON directly in the engine, where we have all the metadata. This is orthogonal to the other branch I'm working on, it shouldn't delay the other changes too much. Worst case, we generate a base JSON schema in the engine and complement it externally, at least while we test and iterate. |
Hi, @daniel-thom, sorry for the extended delay. In part, that's due to the lack of a good complete tool for mapping the JSON Schema to Pydantic. Tools like datamodel-code-generator did not work well enough, but was still a good starting point and helped me familiarize with the related tools. In the end, I wrote a specialized tool. To avoid exposing too much info and muddying the waters, I now think it is better to expose a JSON schema for the input format, and them work on complements for output and so on. There's a lot of progress in various areas:
Regardless of the progress, there will be new releases on this Wednesday. I'll start pushing code by tomorrow. As soon as there are some inspiring examples, I'll drop the links here. To complement that, the new API is almost ready and will fit well in modern code. |
This progress sounds great! We have some use cases that would immediately benefit from this work. If you’re ok with sharing preliminary work, @KapilDuwadi and I could test how it works with our network models. |
@daniel-thom Almost there, doing basic testing today and should push everything to the repos (including the new https://github.com/dss-extensions/AltDSS-Schema) by this time tomorrow. |
@daniel-thom @KapilDuwadi Just pushed most of the main code to the repo. I'll prepare a basic notebook to illustrate some basics and what can already be done, then review and add more notes little by little. The model currently matches the internal OpenDSS very closely since it is generate by DSS C-API. It includes some things that are probably not done on purpose in the engine (like allowing using files for way too many properties). To reach this current version, including the import/export in DSS C-API, I ran various tests, and fixed some important aspects of the definition and tweaked the behavior of the engine. The changelog turned out quite long: https://github.com/dss-extensions/dss_capi/blob/0.14.0b1/docs/changelog.md#version-0140 Sorry I took too long, but I think we have a good base now. |
@PMeira This is fantastic work. There is so much potential to change how researchers use OpenDSS. Once you have published an example, I’ll start propagating this to colleagues. |
@daniel-thom Thanks! I'm checking some final issues with the roundtrips of some test circuits in DSS C-API, but most issues so far have been with the original We should have the final releases based on DSS C-API 0.14.0 after the holidays. I'll make sure to both add some examples and rework the text there by then. |
Feature Request
Is there JSON schema that backs the JSON generated by the new
ToJSON
methods? If not, I would be open to generate it. I’m guessing that it wouldn’t be difficult based on all the versions of data models that already exist.There are many potential use cases for the JSON schema, but I’ll explain mine here. There could be better ways to solve my problem.
My colleagues often do something like this:
There a few basic problems often encountered:
Master.dss
file enables a time-series simulation and so loading the circuit takes a long time - they don’t care about the simulation, just the static values of each circuit element.To work around these problems they string-parse the OpenDSS files and comment-out things they don’t want. This is very prone to bugs.
An ideal solution to this problem would be flags to the
compile
command that disable time-series simulations and loading of load shape data. I am assuming that such an addition to OpenDSS is highly unlikely.Another solution is to generate data models from the JSON schema (such as with the pydantic python library), export the JSON representations of the OpenDSS models into files or a database (one-time cost), and then de-serialize the JSON into Python classes for all transformation work. The Python classes could easily be converted back to OpenDSS text commands when it comes time to generate the new circuits.
A secondary benefit of this JSON solution is that people could run simulations with different load shape profiles more easily. No string manipulation to rewire load-to-loadshape connections would be required. Load shapes could be stored in any file format and passed to OpenDSS in memory.
The text was updated successfully, but these errors were encountered: