Skip to content
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

Support enum #167

Open
jdkandersson opened this issue Aug 22, 2020 · 3 comments
Open

Support enum #167

jdkandersson opened this issue Aug 22, 2020 · 3 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@jdkandersson
Copy link
Owner

As a user I want to define a list of valid values for a variable so that only those values are accepted.

Reference to the OpenAPI documentation: https://swagger.io/docs/specification/data-models/enums/

Requested in #166

@jdkandersson jdkandersson added the enhancement New feature or request label Aug 22, 2020
@jdkandersson jdkandersson added this to the Cleanup milestone Aug 22, 2020
@rgreinho
Copy link
Contributor

I am interested in working on this issue.

@jdkandersson
Copy link
Owner Author

jdkandersson commented Dec 27, 2020

What is supported

  • base types of integer, number and string

What is not supported

  • base types of object and array

High Level Flow

OpenAlchemy follows the following high level steps to produce output:

  1. It validates the schema against any assumptions made (e.g. that a many-to-many relationship is well defined)
  2. It converts the schema to artefacts which are well defined classes in OpenAlchemy
  3. These artefacts are passed to SQLAlchemy in a facade to be converted to columns
  4. The artefacts are passed to a typing engine to generate the models_autogenerated.py files
  5. The models are constructed by inheriting from UtilityBase which adds some helper functions (such as from_dict)

For now, we will park step 4 and 5 for later

Validation

The functionality for validation is defined in the following folder:

open_alchemy/schemas/validation

The first step is break down the problem first to individual schemas and then to properties within those schemas. Then, there are a few different types of properties which is used to break down the problem a little further. The types are:

  • simple
  • json
  • backref
  • relationship

In this case we only need to worry about simple. For each property of this type the schema is passed to the check function in the following file:

open_alchemy/schemas/validation/property_/simple.py

This function needs to be modified to do the following checks if a property defines enum:

  • Check that the value of enum is a list
  • Check that each item within the array is a valid instance of the schema.

These checks should be performed after all other checks so that you can assume that the schema is otherwise valid.

I was looking for a function that could help with the item validation, the best I could find is that something similar is being done for the default function in open_alchemy/helpers/peek.py. I would recommend that a enum function be added to the same file that performs similar validation as default (it might be worth pulling that functionality out of the default function into a separate helper function) as well as the check for a list as above.

Other types

For relationship, a check should be implemented that enum is not defined. It should throw a FeatureNotImplementedError exception. The relevant file is: open_alchemy/schemas/validation/property_/relationship/property_.py

Artefacts

After validation passes, OpenAlchemy converts the schema into well-defined artefacts data classes. The relevant folder is: open_alchemy/schemas/artifacts

Again, the problem is broken down in a similar way as for validation. The relevant file to update is:

open_alchemy/schemas/artifacts/property_/simple.py

Additionally, the class that is returned has to be updated. The class is OpenApiSimplePropertyArtifacts which should have an enum property added (open to better ways of implementing this). This class is defined here:

open_alchemy/types.py

SQLAlchemy model construction

To construct the SQLAlchemy model, the artefacts class needs to be converted to a SQLAlchemy Column which is done in the following file:

open_alchemy/facades/sqlalchemy/simple.py

The mapping should be done to the following SQLAlchemy type:

https://docs.sqlalchemy.org/en/13/core/type_basics.html#sqlalchemy.types.Enum

Example

To verify that everything works up to this point, create an example in the following folder:

examples

And add a test to the following file:

tests/examples/test_example_specs.py

Next Steps

This is potentially enough to do an initial pull request. If you like, after completing each stage (e.g. validation), it would also be fine to do a pull request and have that stage merged into master, it won't break anything (assuming all tests pass) and it means you can more easily keep up with any changes on the master branch.

Let's reconnect after this, there are a few more things that we need to do:

  1. Update some integration tests
  2. Update the models file autogeneration
  3. Add a check for that UtilityBase correctly rejects invalid values due to enum
  4. Maybe some other things I can think of right now 😉

@iamthen0ise
Copy link

Hi! Any news?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants