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

Convert Service to REST using FastAPI and Make ScanSpecs Pydantic Models #56

Merged
merged 41 commits into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
8f2e8f2
Convert from using apischema to pydantic
callumforrester Oct 27, 2022
049e63e
Convert service to a REST API using FastApi
callumforrester Oct 28, 2022
0c3a358
Remove unused import
callumforrester Oct 28, 2022
bc366ef
Convert service dataclasses to pydantic dataclasses
callumforrester Oct 28, 2022
cb069d6
Use dataclasses over BaseModel
callumforrester Oct 28, 2022
d26794a
Use dataclasses over BaseModel
callumforrester Oct 28, 2022
a5d68b4
Add comments
callumforrester Dec 16, 2022
f88f460
Update dependencies in toml
callumforrester Dec 20, 2022
060246c
WIP on restifying
callumforrester Dec 20, 2022
3cf88c1
Use POST in REST API
callumforrester Jan 3, 2023
42a7743
Organise and separate out REST API
callumforrester Jan 3, 2023
64aeb74
Add vscode launch config for service
callumforrester Jan 3, 2023
2971ef6
Fix bugs in REST handlers
callumforrester Jan 3, 2023
18ddc3a
Fix mypy issues with pydantic
callumforrester Jan 3, 2023
888d6f2
Start on service tests
callumforrester Jan 3, 2023
e981a8d
Fix schema generation
callumforrester Jan 3, 2023
ab919fb
More service tests
callumforrester Jan 4, 2023
21ec60c
Fix smallest step calculator so it excludes zeros
callumforrester Jan 4, 2023
12c6afd
Fix service docstrings
callumforrester Jan 4, 2023
5bc927e
Regenerate schema and add test
callumforrester Jan 4, 2023
1662ac4
Fix imports and docstring
callumforrester Jan 4, 2023
0a48947
Fix mypy error with classmethod instantiation
callumforrester Jan 4, 2023
c2f4680
Ensure validation catches validation errors
callumforrester Jan 4, 2023
81160f5
Start on validation docs
callumforrester Jan 4, 2023
4f9a9b2
Fix docs warnings
callumforrester Jan 4, 2023
2b9abf7
Regenerate schema file
callumforrester Jan 4, 2023
c71d9ea
Fix doctests
callumforrester Jan 4, 2023
53aa5bc
Add REST API documentation
callumforrester Jan 4, 2023
e7b5e4b
Remove all references to GraphQL
callumforrester Jan 4, 2023
fa21f80
Improve docstrings in service
callumforrester Jan 4, 2023
1d8df71
Regenerate schema
callumforrester Jan 4, 2023
3ff2e2b
Remove unused imports
callumforrester Jan 4, 2023
0d08bd5
Correct wrong endpoint in docs
callumforrester Jan 4, 2023
ddc2fb9
Enable stricter validation
callumforrester Jan 18, 2023
74a4de3
Don't instantiate config class
callumforrester Jan 18, 2023
73e9a11
More tests to confirm serialization strictness
callumforrester Jan 19, 2023
dd22975
Store models and ref classes in global variables
callumforrester Jan 24, 2023
a84187f
Fix mypy complaints
callumforrester Jan 24, 2023
c6cd016
Add todo for annotated
callumforrester Jan 24, 2023
5cf3d31
Revert "Store models and ref classes in global variables"
callumforrester Jan 24, 2023
d01dac8
Rename magic pydantic properties to get rid of dunders
callumforrester Jan 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ jobs:
matrix:
os: ["ubuntu-latest"] # can add windows-latest, macos-latest
python: ["3.9", "3.10", "3.11"]
install: ["-e .[dev,graphql,plotting]"]
install: ["-e .[dev,service,plotting]"]
# Make one version be non-editable to test both paths of version code
include:
- os: "ubuntu-latest"
python: "3.8"
install: ".[dev,graphql,plotting]"
install: ".[dev,service,plotting]"

runs-on: ${{ matrix.os }}
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
uses: ./.github/actions/install_requirements
with:
requirements_file: requirements-dev-3.x.txt
install_options: -e .[dev,graphql,plotting]
install_options: -e .[dev,service,plotting]

- name: Build docs
run: tox -e docs
Expand Down
21 changes: 20 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@
// https://github.com/microsoft/vscode-python/issues/693
"PYTEST_ADDOPTS": "--no-cov"
},
},
{
"name": "Python (Current File)",
"type": "python",
"request": "launch",
"justMyCode": false,
"console": "integratedTerminal",
"program": "${file}"
},
{
"name": "Scanspec Service",
"type": "python",
"request": "launch",
"justMyCode": false,
"console": "integratedTerminal",
"module": "scanspec",
"args": [
"service"
]
}
]
}
}
8 changes: 4 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@
"sphinx.ext.inheritance_diagram",
# Adds plotting directives
"matplotlib.sphinxext.plot_directive",
# Graphiql directive
"sphinx_graphql.graphiql",
# Makes autodoc understand apischema annotated classes/functions
"sphinx_apischema",
# OpenAPI directive
"sphinxcontrib.openapi",
# Add example_spec directive
"scanspec.sphinxext",
# Add a copy button to each code block
Expand Down Expand Up @@ -77,6 +75,8 @@
("py:class", "'object'"),
("py:class", "'id'"),
("py:class", "typing_extensions.Literal"),
("py:class", "pydantic.config.BaseConfig"),
("py:class", "starlette.responses.JSONResponse"),
]

# Both the class’ and the __init__ method’s docstring are concatenated and
Expand Down
23 changes: 3 additions & 20 deletions docs/how-to/serialize-a-spec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Lets start with an example `Spec`.
This Spec has a `repr` that shows its parameters it was instantiated with:

>>> spec
Product(outer=Line(axis='y', start=4, stop=5, num=6), inner=Line(axis='x', start=1, stop=2, num=3))
Product(outer=Line(axis='y', start=4.0, stop=5.0, num=6), inner=Line(axis='x', start=1.0, stop=2.0, num=3))


How to Serialize
Expand All @@ -20,29 +20,12 @@ How to Serialize
We can recursively serialize it to a dictionary:

>>> spec.serialize()
{'Product': {'outer': {'Line': {'axis': 'y', 'start': 4, 'stop': 5, 'num': 6}}, 'inner': {'Line': {'axis': 'x', 'start': 1, 'stop': 2, 'num': 3}}}}

{'outer': {'axis': 'y', 'start': 4.0, 'stop': 5.0, 'num': 6, 'type': 'Line'}, 'inner': {'axis': 'x', 'start': 1.0, 'stop': 2.0, 'num': 3, 'type': 'Line'}, 'type': 'Product'}

How to Deserialize
------------------

We can turn this back into a spec using `Spec.deserialize`:

>>> Spec.deserialize({'Product': {'outer': {'Line': {'axis': 'y', 'start': 4, 'stop': 5, 'num': 6}}, 'inner': {'Line': {'axis': 'x', 'start': 1, 'stop': 2, 'num': 3}}}})
>>> Spec.deserialize({'outer': {'axis': 'y', 'start': 4.0, 'stop': 5.0, 'num': 6, 'type': 'Line'}, 'inner': {'axis': 'x', 'start': 1.0, 'stop': 2.0, 'num': 3, 'type': 'Line'}, 'type': 'Product'})
Product(outer=Line(axis='y', start=4.0, stop=5.0, num=6), inner=Line(axis='x', start=1.0, stop=2.0, num=3))


How to send it over GraphQL
---------------------------

Every Spec lists in its documentation a list of parameters and types. The GraphQL
representation is the dictionary of these parameters, wrapped in a dictionary
with a single element whose key is the classname. This allows the
deserialization code to pick the correct class to deserialize to. For example::

{Line: {axis: "y", start: 4, stop: 5, num: 6}}

You can use `Spec.to_gql_input` to produce this from an existing spec:

>>> spec.to_gql_input()
'{Product: {outer: {Line: {axis: "y", start: 4, stop: 5, num: 6}}, inner: {Line: {axis: "x", start: 1, stop: 2, num: 3}}}}'
1 change: 1 addition & 0 deletions docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Practical step-by-step guides for the more experienced user.
:caption: Reference

reference/api
reference/rest_api
reference/contributing
Releases <https://github.com/dls-controls/scanspec/releases>
Index <genindex.html#http://>
Expand Down
12 changes: 1 addition & 11 deletions docs/reference/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ from code:
- `scanspec.specs`: `Spec` and its subclasses
- `scanspec.regions`: `Region` and its subclasses
- `scanspec.plot`: `plot_spec` to visualize a scan
- `scanspec.service`: Defines queries and field structure in graphQL such as `PointsResponse`
- `scanspec.service`: Defines queries and field structure in REST such as `MidpointsResponse`

.. data:: scanspec.__version__
:type: str
Expand Down Expand Up @@ -55,16 +55,6 @@ from code:

.. automodule:: scanspec.service
:members:
:exclude-members: abs_diffs, Points, AxisFrames, PointsResponse

``scanspec.service``
--------------------

.. autoclass:: scanspec.service.Points
:members:

.. autoclass:: scanspec.service.AxisFrames
:members:

.. autoclass:: scanspec.service.PointsResponse
:members:
6 changes: 6 additions & 0 deletions docs/reference/rest_api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
REST API
========

The endpoints of the REST service are documented below.

.. openapi:: ../../schema.json
2 changes: 1 addition & 1 deletion docs/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ Tutorials for installation, library and commandline usage. New users start here.

tutorials/installation
tutorials/creating-a-spec
tutorials/graphql-service
tutorials/rest-service
Loading