diff --git a/docs/_static/custom.css b/docs/_static/custom.css index 995f5e7ff..9b0b17650 100644 --- a/docs/_static/custom.css +++ b/docs/_static/custom.css @@ -1,7 +1,26 @@ +/* TOM Toolkit Branding Colors */ +/* --primary: #017792; /* TOM Toolkit logo colors */ +/* --color-primary: #017792; */ +/* --primary-light: #00a3c8; */ + +[data-theme="light"] { + --color-primary: #017792; + --color-header-background: #00a3c8; +} +[data-theme="dark"] { + --color-primary: #017792; + --color-background: #00a3c8; +} + div.partners { text-align: center; } a.hs { padding-right: 10%; +} + +.toctree-l1 > a[href*="getting_started"] { + color: #017792 !important; + font-weight: bold; } \ No newline at end of file diff --git a/docs/_static/managing_data/data_upload_form.png b/docs/_static/managing_data/data_upload_form.png new file mode 100644 index 000000000..ac19de042 Binary files /dev/null and b/docs/_static/managing_data/data_upload_form.png differ diff --git a/docs/_static/observation_module/target_detail_observe_buttons.png b/docs/_static/observation_module/target_detail_observe_buttons.png new file mode 100644 index 000000000..b2c94f96d Binary files /dev/null and b/docs/_static/observation_module/target_detail_observe_buttons.png differ diff --git a/docs/_static/observation_module/target_moon_separation_plot.png b/docs/_static/observation_module/target_moon_separation_plot.png new file mode 100644 index 000000000..0febcbac7 Binary files /dev/null and b/docs/_static/observation_module/target_moon_separation_plot.png differ diff --git a/docs/_static/observation_module/target_visibility_tool.png b/docs/_static/observation_module/target_visibility_tool.png new file mode 100644 index 000000000..3c1a7066d Binary files /dev/null and b/docs/_static/observation_module/target_visibility_tool.png differ diff --git a/docs/brokers/index.rst b/docs/brokers/index.rst deleted file mode 100644 index 4da6fa5df..000000000 --- a/docs/brokers/index.rst +++ /dev/null @@ -1,29 +0,0 @@ -Brokers -======= - -.. toctree:: - :maxdepth: 2 - :hidden: - - create_broker - create_dash_broker - ../api/tom_alerts/brokers - ../api/tom_alerts/views - create_dataservice - - -What is an Alert Broker Module? -------------------------------- - -A TOM Toolkit Alert Broker Module is an object which contains the logic for querying a remote broker -(e.g `ANTARES `_), and transforming the returned data into TOM Toolkit Targets. - -:doc:`Creating an Alert Broker ` - Learn how to add a custom broker module to query for targets from your favorite broker. - -:doc:`Creating a Dash Alert Broker ` - Add a responsive broker module to browse alerts using Plotly Dash. - -:doc:`Broker Modules <../api/tom_alerts/brokers>` - Take a look at the supported brokers. - -:doc:`Broker Views <../api/tom_alerts/views>` - Familiarize yourself with the available Broker Views. - -:doc:`Create Data Service ` - Walk through the creation of your own Data Service. diff --git a/docs/code/index.rst b/docs/code/index.rst index 4ada5532e..f432e70b9 100644 --- a/docs/code/index.rst +++ b/docs/code/index.rst @@ -1,26 +1,55 @@ Interacting with your TOM through code ====================================== -.. toctree:: - :maxdepth: 2 - :hidden: +TOM systems provide a platform for automating some, if not all, of the day-to-day workflow of an +astronomical program. To that end, the Toolkit offers Application Programmable Interfaces (API) for +a number of key functions, and there are a number of options for automating workflows. - querying - automation - backgroundtasks - custom_code - ../common/scripts +Automated Tasks +--------------- -:doc:`Advanced Querying ` - Get a couple of tips on programmatic querying with Django's QuerySet API +There are many tasks which often have to be executed on a regular schedule, such as looking for new potential +targets for instance. Rather than have to do this yourself, you can write a simple script called a ``management command`` +which can be configured to run regularly as a cronjob. -:doc:`Automating Tasks ` - Run commands automatically to keep your TOM working even when you -aren’t +This mechanism is also really helpful if you want to implementing code to analyse the data in the TOM without having to +build it into the user interface. -:doc:`Background Tasks ` - Learn how to set up an asynchronous task library to handle long -running and/or concurrent functions. +:doc:`Automating Tasks ` describes how to implement a ``management command``, and a full list of the +TOM's built-in management commands can be found :doc:`here `. -:doc:`Running Custom Code Hooks ` - Learn how to run your own scripts when certain actions happen -within your TOM (for example, an observation completes). +Asynchronous Tasks +------------------ -:doc:`Scripting your TOM with Jupyter Notebooks <../common/scripts>` - Use a Jupyter notebook (or just a python -console/scripts) to interact directly with your TOM. +Sometimes functions can take a long time to complete, such as data reduction pipelines or queries to external services. +This can be an issue for browser-based systems like TOMs, because the browser has a timeout which may raise an error +before the task completes. Nevertheless, it is often desirable for a TOM system to be able to orchestrate these +tasks. + +An asynchronous task is designed to mitigate this problem; it can be triggered to run in the background by the TOM, and +to return the expected output whenever it is ready. :doc:`Background Tasks ` describes how to set up +an asynchronous task library to handle long running and/or concurrent functions. + +Advanced Queries +---------------- + +Django's QuerySet API provides a range of sophisticated and efficient tools for querying your TOM's database. +:doc:`Advanced Querying ` explores some of the options in more depth. + +Custom Code Hooks +----------------- + +A code hook allows us to tell the TOM to perform a given function whenever a certain action is taken, such as clicking +a button or uploading a file. You can add your own customized functions to the TOM and define when they should +be called following the guidelines in :doc:`Running Custom Code Hooks `. + +Python Scripts and Jupyter Notebooks +------------------------------------ + +You can also interact directly with your TOM from a Python script or Jupyter notebook, which provides a flexible way to +analysis the data. :doc:`Scripting your TOM with Jupyter Notebooks ` shows how. + +API Reference +------------- + +Full details of all TOM Toolkit functions can be found in the :doc:`API Documentation `. \ No newline at end of file diff --git a/docs/api/plugins.md b/docs/code/plugins.rst similarity index 51% rename from docs/api/plugins.md rename to docs/code/plugins.rst index 9d2130758..a26bcc3d5 100644 --- a/docs/api/plugins.md +++ b/docs/code/plugins.rst @@ -1,5 +1,5 @@ TOM Toolkit Plugins -------------------- +=================== We aim to keep the TOM as lightweight and flexible as possible, and we recognize that every team has their own science goals and often need @@ -10,150 +10,225 @@ functions, we support a range of optional plugin modules for the Toolkit. These range from adding the ability to interface with additional observatories and catalogs, to providing additional plotting or data analytics functionality. -### [tom_hermes](https://github.com/TOMToolkit/tom_hermes) +tom_hermes +---------- + +`Github link `_ -The [Hermes](https://hermes.lco.global) service provides a archive of +The `Hermes `_ service provides a archive of astronomical alerts. This plugin allows TOM users to query Hermes and share data with the service. -### [tom_fink](https://github.com/TOMToolkit/tom_fink) +tom_fink +-------- -[Fink](https://fink-broker.org/) is an alert broker service. This plugin +`Github link `_ + +`Fink `_ is an alert broker service. This plugin enables users to query this service and harvest alert information. -### [tom_antares](https://github.com/TOMToolkit/tom_antares) +tom_antares +----------- + +`Github link `_ -This plugin adds support for querying the [ANTARES](https://antares.noirlab.edu/) broker for targets of interest. +This plugin adds support for querying the `ANTARES `_ broker for targets of interest. -### [tom_app_template](https://github.com/TOMToolkit/tom_app_template) +tom_app_template +---------------- + +`Github link `_ This repository is designed to provide a starting template for TOM users wishing to develop their own TOM app. This app contains all of the basic workflows, directory structure, testing infrastructure, and instructions you will need to get started. -### [tom_jpl](https://github.com/TOMToolkit/tom_jpl) +tom_jpl +------- + +`Github link `_ The Jet Propulsion Laboratory provides a number of services supporting Solar System science. This plugin provides a TOM interface to JPL's -[SCOUT](https://cneos.jpl.nasa.gov/scout/intro.html) service. +`SCOUT `_ service. + +tom_eso +------- -### [tom_eso](https://github.com/TOMToolkit/tom_eso) +`Github link `_ This plugin enables users to compose and submit observation requests to -telescopes at the [European Southern Observatory](https://www.eso.org/public/). +telescopes at the `European Southern Observatory `_. -### [tom_regions](https://github.com/TOMToolkit/tom_regions) +tom_regions +----------- + +`Github link `_ This plugin allows a TOM to store sky regions defined from Multi-Order Coverage maps. -### [tom_registration](https://github.com/TOMToolkit/tom_registration) +tom_registration +---------------- + +`Github link `_ This plugin introduces support for two TOM registration -workflows--an open registration, and a registration that requires administrator approval. +workflows including an open registration, and a registration that requires administrator approval. -### [tom_tns](https://github.com/TOMToolkit/tom_tns) +tom_tns +------- + +`Github link `_ This plugin enables TOMs to report transient classifications to -the [Transient Name Server](https://www.wis-tns.org/). +the `Transient Name Server `_. + +tom_alertstreams +---------------- -### [tom_alertstreams](https://github.com/TOMToolkit/tom_alertstreams) +`Github link `_ Apache Kafka is widely used in astrophysics for the dissemination of alert packages. This plugin enables a TOM system to listen to user-configured alerts streams. -### [tom_demoapp](https://github.com/TOMToolkit/tom_demoapp) +tom_demoapp +----------- + +`Github link `_ This TOM application is not designed to be installed by users, but instead act as a development and demonstration app for users wishing to integrate their own TOM applications with the base TOM toolkit. The code itself serves as example, -while the [wiki](https://github.com/TOMToolkit/tom_demoapp/wiki) gives a menu of existing integration points. +while the `wiki `_ gives a menu of existing integration points. + +tom_nonlocalizedevents +---------------------- -### [tom_nonlocalizedevents](https://github.com/TOMToolkit/tom_nonlocalizedevents) +`Github link `_ Various events in astrophysics are hard to localize, for example gravitational wave or neutrino detections. This app allows the TOM to recognize that a given event may be associated with a number of candidates, and provides custom views designed to support this workflow. -### [tom_swift](https://github.com/TOMToolkit/tom_swift) +tom_swift +--------- + +`Github link `_ -The [Neil Gehrels Swift Observatory](https://swift.gsfc.nasa.gov/) is a space telescope offering +The `Neil Gehrels Swift Observatory `_ is a space telescope offering UV/Visible and X-ray instrumentation and rapid response capabilities. This plugin enables TOM users to submit requests for Target of Opportunity observations with this spacecraft. -### [tom_classifications](https://github.com/TOMToolkit/tom_classifications) +tom_classifications +------------------- + +`Github link `_ This app provides a number of data visualization tools for inspecting alert data from multiple brokers. -### [tom_keck](https://github.com/TOMToolkit/tom_keck) +tom_keck +-------- + +`Github link `_ Application to enable requests for Target of Opportunity observations -to be submitted to the [Keck Observatories](https://keckobservatory.org/). -Note: to be integrated with [AEONlib](https://github.com/AEONplus/AEONlib). +to be submitted to the `Keck Observatories `_. +Note: to be integrated with `AEONlib `_. + +tom-lt +------ -### [tom-lt](https://github.com/TOMToolkit/tom_lt) +`Github link `_ This module provides the ability to submit observations to the -[Liverpool Telescope](https://telescope.livjm.ac.uk/) Phase 2 system. It is in a very alpha +`Liverpool Telescope `_ Phase 2 system. It is in a very alpha state, with little error handling and minimal instrument options, but can successfully submit well-formed observation requests. -### [tom-toolkit_component_lib](https://github.com/TOMToolkit/tom-toolkit-component-lib) +tom-toolkit_component_lib +------------------------- + +`Github link `_ Demonstration of how Javascript front-end components can be integrated with a TOM. -### [tom_dash](https://github.com/TOMToolkit/tom_dash) +tom_dash +-------- + +`Github link `_ -This module demonstrates how [Plotly-Dash](https://dash.plotly.com/) components can be added to a +This module demonstrates how `Plotly-Dash `_ components can be added to a TOM for data exploration and visualization. -### [tom_gemini_community](https://github.com/TOMToolkit/tom_gemini_community) +tom_gemini_community +-------------------- + +`Github link `_ TOM module to enable observations to be submitted to the -[Gemini Telescope's](http://www.gemini.edu/) Phase 2 system. +`Gemini Telescope's `_ Phase 2 system. -### [tom_nonsidereal_airmass](https://github.com/TOMToolkit/tom_nonsidereal_airmass) +tom_nonsidereal_airmass +----------------------- -This plugin provides a templatetag -that supports plotting for non-sidereal objects. The plugin is fully supported by the TOM Toolkit team; however, +`Github link `_ + +This plugin provides a templatetag that supports plotting for non-sidereal objects. The plugin is fully supported by the TOM Toolkit team; however, non-sidereal visibility calculations require the PyEphem library, which is minimally supported while its successor is in development. The library used for the TOM Toolkit sidereal visibility, astroplan, does not yet support non-sidereal visibility calculations. -### [tom_publications](https://github.com/TOMToolkit/tom_publications) +tom_publications +---------------- + +`Github link `_ This application prototyped tools to enable users to output latex-formatted data from their TOM system. -### [herokutom](https://github.com/TOMToolkit/herokutom) +herokutom +--------- + +`Github link `_ This repository demonstrates how a TOM system can be deployed to a public -server using the [Heroku platform](https://www.heroku.com/). +server using the `Heroku platform `_. -## Archived plugins +Archived plugins +---------------- The following plugins are available but not currently supported. In some cases this is because the functionality has been integrated with the base Toolkit. -### [tom_alerts_dash](https://github.com/TOMToolkit/tom_alerts_dash) +tom_alerts_dash +--------------- + +`Github link `_ This plugin adds responsive ReactJS views to the `tom_alerts` module for supported brokers. The `tom_alerts` module has been superseded by tom_dataservices in v3.0.0. -### [dockertom](https://github.com/TOMToolkit/dockertom) +dockertom +--------- + +`Github link `_ This repository demonstrates how to package a TOM system in a docker container, which is often required for deployment. -### [tom_scimma](https://github.com/TOMToolkit/tom_scimma) +tom_scimma +---------- + +`Github link `_ This app enables a TOM to subscribe to the Hopskotch alert stream developed by the Scalable Cyberinfrastructure to support Multi‑Messenger Astrophysics -([SCiMMA](https://scimma.org/)) project. +(`SCiMMA `_) project. diff --git a/docs/common/customsettings.rst b/docs/common/customsettings.rst index 454988919..d5b572bae 100644 --- a/docs/common/customsettings.rst +++ b/docs/common/customsettings.rst @@ -1,5 +1,5 @@ TOM Specific Settings ---------------------- +===================== The following is a list of TOM Specific settings to be added/edited in your project’s ``settings.py``. For explanations of Django specific @@ -222,7 +222,7 @@ A list of tom alert classes to make available to your TOM. If you have written or downloaded additional alert classes you would make them available here. If you’d like to write your own alert module please see the documentation on :doc:`Creating an Alert Module for the TOM -Toolkit <../brokers/create_broker>`. +Toolkit `. `TOM_ALERT_DASH_CLASSES <#tom-alert-dash-classes>`__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -239,7 +239,7 @@ Default: A list of tom alert dash classes to make available to your TOM. If you have written or downloaded additional alert classes you would make them available here. If you’d like to write your own dash alert module, please see -the documentation on :doc:`Plotly Dash Broker Modules in the TOM Toolkit <../brokers/create_dash_broker>`. +the documentation on :doc:`Plotly Dash Broker Modules in the TOM Toolkit `. `TOM_FACILITY_CLASSES <#tom-facility-classes>`__ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/common/index.rst b/docs/common/index.rst new file mode 100644 index 000000000..ea6d52e35 --- /dev/null +++ b/docs/common/index.rst @@ -0,0 +1,27 @@ +Configuring a TOM +================= + +TOM Settings +------------ + +TOMs have a number of configurable settings that are needed for various functions. +Since the Toolkit is based on the `Django framework `__ +most of these options are controlled via the settings.py file. You'll find this +is created for you when you initialize a new TOM: + +.. code:: + + mytom/ + | mytom/ + |- settings.py + ... + +The admin of the TOM can edit this file to set the parameters as desired. A full list of the +configurable options is given :doc:`here` + +Permissions +----------- + +TOM systems can have hundreds or thousands of users and we recognize that sometimes it is desirable to control +who can access what data or functions. The Toolkit provides fine-grained control over user permissions, as documented +:doc:`here`. diff --git a/docs/conf.py b/docs/conf.py index 2fa68b4e0..eb1de9674 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -4,116 +4,47 @@ # list see the documentation: # http://www.sphinx-doc.org/en/master/config -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# import os import sys import django -import sphinx_rtd_theme - -from recommonmark.parser import CommonMarkParser - -from tom_base import __version__ - -sys.path.insert(0, os.path.abspath('..')) - - -# -- Project information ----------------------------------------------------- -project = 'TOM Toolkit' -copyright = '2021-6, Las Cumbres Observatory' -author = 'Joey Chatelain, David Collom, Lindy Lindstrom, Austin Riba' - -# The full version, including alpha/beta/rc tags -# This has to mirror the setup.py version for PDF generation -release = __version__ - -# -- Django Configuration ------------------------------------------------- - -# import os -# import sys -# import django -# sys.path.insert(0, os.path.abspath('..')) os.environ['DJANGO_SETTINGS_MODULE'] = 'tom_base.settings' django.setup() +sys.path.insert(0, os.path.abspath("..")) -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.autosectionlabel', - 'sphinx.ext.autosummary', - 'sphinx.ext.intersphinx', - 'sphinx_design', - 'sphinx_copybutton', + "sphinx.ext.autodoc", + "sphinx.ext.viewcode", + "sphinx_breeze_theme", + "myst_parser", + "sphinx_design", ] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# source_parsers = { -# '.md': 'recommonmark.parser.CommonMarkParser', -# } - -# source_suffix = ['.rst', '.md'] - -# autodoc_mock_imports = ['rise-set'] -autodoc_inherit_docstrings = False -autodoc_default_options = { - # 'members': True, - 'member-order': 'bysource', - # 'special-members': '__init__', -} -autoclass_content = 'both' - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. - -html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html', - 'searchbox.html', - 'donate.html', - ] +templates_path = ["_templates"] +source_suffix = { + ".rst": "restructuredtext", + ".txt": "markdown", + ".md": "markdown", } - +master_doc = "index" +project = "TOM Toolkit" +copyright = "2026, Las Cumbres Observatory" +author = "Joey Chatelain, David Collom, Lindy Lindstrom, Austin Riba, Rachel Street" + +language = "en" +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "requirements.txt"] +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False +today_fmt = "%Y-%m-%d %H:%M" + +# -- Options for HTML output ------------------------------------------- +html_theme = "breeze" +html_show_sphinx = True html_static_path = ['_static'] -html_theme = 'alabaster' -# html_theme = 'sphinx_rtd_theme' - -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] -html_theme_options = { - 'logo': 'logo-color.png', - 'logo_name': 'false', - 'github_repo': 'tom_base', - 'github_button': 'false', -} - -pygments_style = 'sphinx' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ['_static'] +html_css_files = ["custom.css"] +html_favicon = "_static/logo-color.png" +github_doc_root = "https://github.com/TOMToolkit/tom_base/tree/dev/docs" def setup(app): - app.add_source_suffix('.md', 'markdown') - app.add_source_parser(CommonMarkParser) + pass diff --git a/docs/customization/index.rst b/docs/customization/index.rst index 561d13ef0..5f8751e00 100644 --- a/docs/customization/index.rst +++ b/docs/customization/index.rst @@ -1,36 +1,78 @@ Customization ============= -.. toctree:: - :maxdepth: 2 - :hidden: +The TOM Toolkit is deliberately designed as an adaptable framework to enable users to customize +all aspects of it. This includes both "look and feel" aspects of the appearance of the user interface, +to adding new functionality and automating aspects of your workflow. - customize_templates - adding_pages - customize_template_tags - testing_toms - widgets - encrypted_model_fields - htmx_tables +The :doc:`Programming Resources ` page provides some quick links to a number of useful reference sources +relating to software used in the TOM Toolkit: HTML, CSS, Python, and Django +User Interface Appearance and Layout +------------------------------------ -Start here to learn how to customize the look and feel of your TOM or add new functionality. +The TOM's user interface is built on top of `Django's template engine `_. +This template system allows us to design pages which can be populated with variables and even functions called ``templatetags``, +to adapt the content and provide functionality - without duplication of content. -:doc:`Customizing TOM Templates ` - Learn how to override built in TOM templates to -change the look and feel of your TOM. +The Toolkit provides a number of built-in templates which you can see in the out-of-the-box TOM system. +Any or all of these templates can be overridden if you want to change the color palette or even the entire layout. +:doc:`Customizing TOM Templates ` describes how to do this. -:doc:`Adding new Pages to your TOM ` - Learn how to add entirely new pages to your TOM, -displaying static html pages or dynamic database-driven content. +We provide a library of widgets to perform common functions, such as buttons. +:doc:`TOM Widgets ` describes how to make use of these in your page. -:doc:`Customizing Template Tags ` - Learn how to write your own template tags to display -the data you need. +Adding Pages and Functionality +------------------------------ -:doc:`Testing TOMs ` - Learn how to test your TOM's functionality. +You can also add entirely new pages to the TOM user interface, to display either static content or display and interact +with data in the database. The process for doing this is described in +:doc:`Adding new Pages to your TOM `. -:doc:`TOM Widgets ` - Include these widgets in your custom templates. +Alternatively, you may not need to add a whole new page, but would like to "embed" a function to display data in +a customized way within an existing page. In that case, you probably want to develop a new `templatetag +`_. +:doc:`This page ` describes how to do this. -:doc:`Encrypting Data in a Model Field ` - Learn how to encrypt sensitive data like -passwords and API keys in your TOMToolkit app. -:doc:`Building Interactive HTMX Tables ` - Learn how to build interactive tables with -filtering, sorting, and pagination using django-tables2 and HTMX. \ No newline at end of file +Data Visualization Tools +------------------------ + +The data visualization tools in the Toolkit include a number of interactive plots and skymaps. You can add +your own custom plots following the guidelines in :doc:`Creating Plots from TOM Data `. + +We are increasingly using `HTMX `_ within the Toolkit to provide more responsive interactive elements +such as search functions, while minimizing the Toolkit's dependency on Javascript. This choice helps us minimize the +user learning curve (though you're welcome to use Javascript if you like!). One area where HTMX has proven useful is in +in the interactive table search functions. :doc:`Click here ` to learn how to build interactive tables with +filtering, sorting, and pagination using django-tables2 and HTMX. + +Custom Code Hooks +----------------- + +Code hooks provide a mechanism for triggering a pre-defined action whenever a certain condition happens. +One example of this is the TOM's data processors which are triggered whenever a data product is uploaded, but you +can easily imagine many other use cases within your workflow. + +:doc:`Running Custom Code Hooks ` demonstrates how to implement you own custom code hook. + +Encrypting Sensitive Data +------------------------- + +Some data held in a TOM can be sensitive, such as user passwords. For security's sake, it is best that these fields +are encrypted, and the TOM provides support for this. :doc:`Click here ` to learn how to +make use of encrypted fields your TOMToolkit app. + +Testing +------- + +If you implement new features, it is a very good idea to include unit tests to verify that the functionality works, +both right now and after future upgrades. To test your TOM's functionality, see :doc:`Testing TOMs `. + +Asynchronous Tasks +------------------ + +If a function is expected to take more than a few minutes - for example a data reduction pipeline - it is advisable +to consider implementing it as an asynchronous task. This will avoid the browser timing out while the task is executing. + +More information on implementing asynchronous tasks within a TOM can be found in :doc:`Background Tasks `. diff --git a/docs/brokers/create_broker.rst b/docs/dataservices/create_broker.rst similarity index 100% rename from docs/brokers/create_broker.rst rename to docs/dataservices/create_broker.rst diff --git a/docs/brokers/create_dash_broker.rst b/docs/dataservices/create_dash_broker.rst similarity index 100% rename from docs/brokers/create_dash_broker.rst rename to docs/dataservices/create_dash_broker.rst diff --git a/docs/brokers/create_dataservice.rst b/docs/dataservices/create_dataservice.rst similarity index 100% rename from docs/brokers/create_dataservice.rst rename to docs/dataservices/create_dataservice.rst diff --git a/docs/dataservices/index.rst b/docs/dataservices/index.rst new file mode 100644 index 000000000..65c88370c --- /dev/null +++ b/docs/dataservices/index.rst @@ -0,0 +1,33 @@ +Dataservices +============ + +There are many sources of data in astrophysics, including alert brokers, data archives, data sharing facilities and +forced photometry services. Many services offer a number of functions. TOM's dataservices module provides interfaces to +enable users to query these services and retrieve data from them for further analysis in the TOM. + +Built-in Dataservices +--------------------- +The Toolkit includes built-in modules to query widely-used public services, including: + +* `Simbad `__ +* `The Transient Name Server `__ +* `ANTARES alert broker `__ +* `Fink alert broker `__ +* `ALeRCE alert broker `__ +* `Hermes `__ +* `JPL SCOUT `__ + +More information on these interfaces is summarized in :doc:`Broker Modules `, and +:doc:`Broker Views ` describes the views available. + +Adding Dataservices +------------------- + +The Toolkit is designed to be extensible and we welcome contributed modules. If you're interested +in developing a dataservice for your own science, here are some resources to get you started. + +:doc:`Creating an Alert Broker ` - Learn how to add a custom broker module to query for targets from your favorite broker. + +:doc:`Creating a Dash Alert Broker ` - Add a responsive broker module to browse alerts using Plotly Dash. + +:doc:`Create Data Service ` - Walk through the creation of your own Data Service. diff --git a/docs/deployment/index.rst b/docs/deployment/index.rst index 8b7e6f5fb..603f78627 100644 --- a/docs/deployment/index.rst +++ b/docs/deployment/index.rst @@ -1,19 +1,43 @@ Deploying your TOM Online ========================= -.. toctree:: - :maxdepth: 2 - :hidden: +Once you’ve got a TOM up and running on your machine (aka ``localhost``), it's advantageous to deploy to a +webhosting service so that it is accessible by you and your colleagues worldwide. - deployment_tips - deployment_heroku - amazons3 +There are a number of different ways of doing this, either by hosting the TOM on a local webserver, or by +deploying it to a Cloud-based service. -Once you’ve got a TOM up and running on your machine, you’ll probably want to deploy it somewhere so it is permanently -accessible by you and your colleagues. +Whichever option you choose, there are some essential decisions to make, including some security settings that it's +important to get right. :doc:`General Deployment Tips ` covers these fundamentals. -:doc:`General Deployment Tips ` - Read this first before deploying your TOM for others to use. +Dockerizing your TOM +-------------------- -:doc:`Deploy to Heroku ` - Heroku is a PaaS that allows you to publicly deploy your web applications without the need for managing the infrastructure yourself. +Docker is a software packaging system which creates a container that ensures the software has a well-defined +environment in which to run -- including all necessary dependencies. This has become widely used and is often +a necessary first step to deploying your TOM. An example repository of a dockerized TOM system can be found +`here `_ for reference. -:doc:`Using Amazon S3 to Store Data for a TOM ` - Enable storing data on the cloud storage service Amazon S3 instead of your local disk. \ No newline at end of file +Local Server +------------ + +Many institutions have their own in-house servers on which they host their own websites. If that is the case at +your institution, then talk to your IT department about hosting your TOM from a local server - every institution +has a distinct configuration. + +Cloud Server +------------ + +There are a number of Cloud service providers that can host a TOM system, including Heroku, Google Cloud, Azure and +Amazon Web Service (AWS). It's worth noting that while Github offers the github.io service, this is designed for +relatively static content in Markdown format rather than database-driven services like a TOM system. + +Heroku offers one of the most straight-forward deployment workflows, without the need for managing the infrastructure yourself, +so we use this as a guide to the process in :doc:`Deploy to Heroku `. + +Data storage +------------ + +Cloud providers also offer general-purpose data storage, which is often value for TOM-related data products. +:doc:`Using Amazon S3 to Store Data for a TOM ` demonstrates how to enable storing data on the cloud storage +service Amazon S3 instead of your local disk. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 829408a3b..f6dfa7772 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,89 +1,83 @@ -Welcome to the TOM Toolkit's documentation! -=========================================== - -.. button-link:: introduction/getting_started.html - :color: info - - Quickstart Guide +TOM Toolkit +=========== .. toctree:: - :maxdepth: 3 + :maxdepth: 2 :hidden: - introduction/credits - introduction/index - introduction/about - introduction/support - introduction/troubleshooting + Getting started + Configuration + Targets + Dataservices + Observing + Data + Customization + API + Deploy + Plugins + Support Introduction ------------ -The TOM (Target and Observation Manager) Toolkit project was started in early 2018 with the goal of simplifying the development of next generation software for the rapidly evolving field of astronomy. Read more :doc:`about TOMs` and the motivation for them. - -:doc:`TOM Toolkit Architecture ` - This document describes the architecture of the TOM Toolkit at a -high level. Read this first if you're interested in how the TOM Toolkit works. - -:doc:`Getting Started with the TOM Toolkit` - First steps for getting a TOM up and running. - -:doc:`TOM Workflow ` - The general workflow used with TOMs. - -:doc:`Programming Resources ` - Resources for learning the core components of the TOM Toolkit: -HTML, CSS, Python, and Django - -:doc:`Frequently Asked Questions ` - Look here for a potential quick answer to a common question. - -:doc:`Troubleshooting ` - Find solutions to common problems or information on how to debug an issue. - -Interested in seeing what a TOM can do? Take a look at our `demonstration TOM `_, where we show off the features of the TOM Toolkit. - -If you'd like to know what we're working on, check out the `TOM Toolkit project board `_. +Target and Observation Manager systems (TOMs, aka marshals) are designed to help researchers +to manage all aspects of astronomical programs. With data rates and volumes increasing, keeping track of +all targets, data products and observations can be a challenge. A TOM system provides a flexible database +of all project information, with a built-in observation and data analysis control system, +together with communication and data visualization tools. +Hundreds of users can then use them to collaborate scientifically, share results and to coordinate +the acquisition of new data. +The TOM (Target and Observation Manager) Toolkit is designed to make it easy for astronomers to build +and customize a TOM system for their science goals. The package includes a full-featured TOM system +out of the box, and this documentation describes how you can extend this system for your own needs. -Topics ------- +More information about TOM systems and the TOM Toolkit project can be found in :doc:`here`. -.. toctree:: - :maxdepth: 2 - :hidden: +Installation & Configuration +---------------------------- - targets/index - brokers/index - observing/index - managing_data/index - customization/index - common/permissions - common/latex_generation - code/index - deployment/index - common/customsettings +Full instructions for installing the package and creating your own TOM system can be found in :doc:`getting started`. +A range of common configuration options are covered in :doc:`custom settings`, including options +to control user permissions. -:doc:`Targets ` - Learn all about how to manage Targets in a TOM. +TOM Demo Example System +----------------------- -:doc:`Brokers ` - Find out about querying brokers in the TOM, which are available, and writing your own. +It's always helpful to have template projects as a reference, so we run a `TOM demo system `__ +where you can explore the TOM's features. If you want to see how this was done, you can explore the code on +`Github `__. -:doc:`Observing ` - Tutorials on submitting observations, customizing submission, and the available facilities. +Customizing your system +----------------------- -:doc:`Managing Data ` - Customize plots, upload data, and even integrate a data reduction pipeline. +The TOM is designed to be flexible, and there are a number of ways to customize it, from the look and feel of its +user interface, to adding science-specific parameters to each target to adding custom functions and applications. +All of these options are described :doc:`here`. -:doc:`Customization ` - Customize and create new views in your TOM. - -:doc:`The Permissions System ` - Use the permissions system to limit access to targets in your TOM. +Plugins +------- -:doc:`LaTeX Generation ` - Generate data tables for your targets and observations +In addition to the features of the base TOM, we also support a range of optional plugin modules. +These extend the functions of the TOM in various ways that are useful for many users. Examples include data visualization +tools for specific science goals, and interfaces for observations with additional telescope facilities. +Click :doc:`here` to browse the list of options. -:doc:`Interacting with your TOM through code ` - Learn how to programmatically interact with your TOM. +Support +------- -:doc:`Deploying your TOM Online ` - Resources for deploying your TOM to a cloud provider +Looking for help? Want to request a feature? Have questions about Github Issues? Take a look at the :doc:`support guide +`. -:doc:`TOM Settings ` - Reference and description for the available settings values to be added to/edited in your project's ``settings.py``. +If you just need an idea, checkout out the :doc:`examples` of existing TOMs built with the TOM Toolkit. Contributing ------------ +The TOM Toolkit is a community-driven project and we welcome feedback and contributions from our users! If you find an issue, you need help with your TOM, you have a useful idea, or you wrote a module you'd like to be -included in the TOM Toolkit, start with the :doc:`Contribution Guide `. +included in the TOM Toolkit, start with our :doc:`contribution guide `. Acknowledging the TOM Toolkit ----------------------------- @@ -92,52 +86,11 @@ We hope you find our software useful for your research. If so, we would be grat if you can include a brief acknowledgement in your papers and presentations, for example "This research made use of `The TOM Toolkit `_". We would also very much appreciate you including a citation to our paper describing -the Toolkit `Street, R.A. et al., 2018, SPIE, 10707, 11 `_ +the Toolkit `Street, R.A. et al., 2018, SPIE, 10707, 11 `_ (to export the BibTeX please click `here `_). -.. toctree:: - :maxdepth: 1 - - introduction/acknowledging_tom_toolkit - -Support -------- - -Looking for help? Want to request a feature? Have questions about Github Issues? Take a look at the :doc:`support guide -`. - -If you just need an idea, checkout out the :doc:`examples` of existing TOMs built with the TOM Toolkit. - -.. toctree:: - :maxdepth: 1 - :hidden: - - examples - introduction/contributing - Releases - Release Notes - Github - -API Documentation ------------------ - -.. toctree:: - :maxdepth: 2 - - api/modules - api/plugins - api/affiliated - -****************** -Indices and tables -****************** - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -About the TOM Toolkit ---------------------- +Acknowledgements +---------------- The TOM Toolkit is managed by Las Cumbres Observatory, with generous financial support from the `National Science Foundation `_ grant 2209852. @@ -145,5 +98,4 @@ We are also grateful for support from the `Heising-Simons Foundation `_ and the `Zegar Family Foundation `_ at the start of the project. - Read about the project and the motivations behind it on the :doc:`About page `. diff --git a/docs/introduction/about.rst b/docs/introduction/about.rst index d8ed67ce5..3ac40e98c 100644 --- a/docs/introduction/about.rst +++ b/docs/introduction/about.rst @@ -1,10 +1,10 @@ -About the TOM Toolkit ---------------------- +TOM systems and the TOM Toolkit Project +======================================= What’s a TOM? -~~~~~~~~~~~~~ +------------- -It stands for Target and Observation Manager, and its a software package +It stands for Target and Observation Manager (aka marshal), and its a software package designed to facilitate astronomical observing projects and collaborations. @@ -31,7 +31,7 @@ TOM systems perform some or all of these functions: - Facilitate the sharing of information and data. Motivation for a TOM Toolkit -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +---------------------------- Many projects, from several branches of astronomy, have found it necessary to develop TOM systems. Current examples include the PTF @@ -60,8 +60,18 @@ What’s needed is a software package that lets astronomers easily build a TOM, customized to suit the needs of their project, without becoming an IT expert or software engineer. +TOM Architecture and Workflow +----------------------------- + +For a high-level overview of the architecture of the TOM Toolkit, see :doc:`Architecture . + +The architecture was designed around a general workflow common to many different areas of astronomy, +particularly time domain and multi-messenger astrophysics. An overview of the workflow is described +:doc:`here `. + + Financial Support -~~~~~~~~~~~~~~~~~ +----------------- The TOM Toolkit is managed by Las Cumbres Observatory, with generous financial support from the `National Science Foundation `_ grant 2209852. diff --git a/docs/introduction/getting_started.rst b/docs/introduction/getting_started.rst index 704ba167f..f95afa831 100644 --- a/docs/introduction/getting_started.rst +++ b/docs/introduction/getting_started.rst @@ -1,8 +1,5 @@ -Getting Started with the TOM Toolkit ------------------------------------- - -So you’ve decided to run a Target and Observation Manager system. This article will -help you get started. +Getting Started +=============== The TOM Toolkit is a `Django `__ project. This means you’ll be running an application based on the Django @@ -16,7 +13,7 @@ likely won’t need to utilize any advanced features. Ready to go? Let’s get started. Quickstart -~~~~~~~~~~ +---------- The easiest way to getting a TOM system up and running on a Linux or Mac is to use our make-tom script. If you would rather install the TOM manually, you can follow the instructions in the :doc:`Manual Installation @@ -50,7 +47,7 @@ Your TOM should now be initialized, and you are ready to spin up a server. .. _runserver: Running the dev server -~~~~~~~~~~~~~~~~~~~~~~ +---------------------- Now that your TOM has been built you can run it immediately, directly on your local machine, using the command ``runserver``: @@ -61,4 +58,11 @@ your local machine, using the command ``runserver``: Now, if you open a web browser, you can navigate to the URL `http://127.0.0.1:8000 `_ and you should see your -new TOM up and running! Go ahead and login to explore what it can do. \ No newline at end of file +new TOM up and running! Go ahead and login to explore what it can do. + +Manual Installation +------------------- + +If you would prefer to install the TOM yourself, full instructions can be +found in our :doc:`Manual Installation +Guide `. \ No newline at end of file diff --git a/docs/introduction/index.rst b/docs/introduction/index.rst deleted file mode 100644 index f891498f1..000000000 --- a/docs/introduction/index.rst +++ /dev/null @@ -1,27 +0,0 @@ -Introduction -============ - -.. toctree:: - :maxdepth: 2 - :hidden: - - tomarchitecture - getting_started - workflow - resources - faqs - troubleshooting - -:doc:`Architecture ` - This document describes the architecture of the TOM Toolkit at a -high level. Read this first if you're interested in how the TOM Toolkit works. - -:doc:`Getting Started ` - First steps for getting a TOM up and running. - -:doc:`Workflow ` - The general workflow used with TOMs. - -:doc:`Programming Resources ` - Resources for learning the elements of programming used in the TOM Toolkit: -HTML, CSS, Python, and Django - -:doc:`Frequently Asked Questions ` - Look here for a potential quick answer to a common question. - -:doc:`Troubleshooting ` - Find solutions to common problems or information on how to debug an issue. \ No newline at end of file diff --git a/docs/introduction/resources.rst b/docs/introduction/programming_resources.rst similarity index 100% rename from docs/introduction/resources.rst rename to docs/introduction/programming_resources.rst diff --git a/docs/introduction/support.rst b/docs/introduction/support.rst index 5a8b98d23..d62d54865 100644 --- a/docs/introduction/support.rst +++ b/docs/introduction/support.rst @@ -26,4 +26,5 @@ Like issues, feature and enhancement requests should be done via the same `Githu Support ------- -If you're looking for help with some aspect of your TOM, the `Github issues page `_ is once again the place to go. The "question" or "help wanted" tags should be very useful when looking for support, and the TOM Toolkit developers are more than happy to provide the help necessary to get your TOM running. You may also want to peruse the `Closed Issues `_, where someone may have already had (and solved!) your problem. \ No newline at end of file +If you're looking for help with some aspect of your TOM, the `Github issues page `_ is once again the place to go. The "question" or "help wanted" tags should be very useful when looking for support, and the TOM Toolkit developers are more than happy to provide the help necessary to get your TOM running. You may also want to peruse the `Closed Issues `_, where someone may have already had (and solved!) your problem. + diff --git a/docs/introduction/tomarchitecture.rst b/docs/introduction/tomarchitecture.rst index b9fe01c5f..aa8bc9405 100644 --- a/docs/introduction/tomarchitecture.rst +++ b/docs/introduction/tomarchitecture.rst @@ -38,7 +38,7 @@ Django framework. This provides several advantages: We **highly recommend** that developers interested in utilizing the TOM Toolkit familiarize themselves with the basics of Django, especially if they want to -customize the toolkit in any significant fashion. The majority of the :doc:`guides found in the TOM toolkit documentation ` are simply Django concepts rewritten in a TOM context. +customize the toolkit in any significant fashion. Extending and Customizing the TOM Toolkit ========================================= @@ -47,13 +47,13 @@ As mentioned before, Django is well known for its extensibility and modularity. The toolkit takes advantage of these strengths heavily. In many ways, the TOM Toolkit is a framework within a framework. -After a TOM developer follows the :doc:`getting started guide ` +After a TOM developer follows the :doc:`getting started guide ` they are left with a functioning but generic TOM. It is then up to the developer to implement the specific features that their science case requires. The toolkit tries to facilitate this as efficiently as possible and provides -:doc:`documentation ` in areas of customization from :doc:`changing the HTML layout of a page ` +:doc:`documentation ` in areas of customization from :doc:`changing the HTML layout of a page ` to :doc:`customizing an OCS facility and forms ` and even -:doc:`creating a new alert broker `. +:doc:`creating a new alert broker `. Django, and by extension the toolkit, rely heavily on object oriented programming, especially inheritance. Most customization in the TOM toolkit comes diff --git a/docs/introduction/workflow.rst b/docs/introduction/workflow.rst index 64fd9b74a..bf56584af 100644 --- a/docs/introduction/workflow.rst +++ b/docs/introduction/workflow.rst @@ -1,8 +1,8 @@ TOM Workflow ------------- +============ Targets -~~~~~~~ +------- Targets are the central entity of the TOM Toolkit. Most functionality in the toolkit requires a target as they are the object of study. A target @@ -11,7 +11,7 @@ usually represented using coordinates on the sky along with other meta data. Creating Targets -^^^^^^^^^^^^^^^^ +---------------- The TOM Toolkit provides a variety of methods for importing astronomical targets into the TOM: @@ -36,14 +36,14 @@ targets into the TOM: information that they know of. Observations -~~~~~~~~~~~~ +------------ After creating targets, the scientist needs to collect data on these targets. The TOM Observing module provides an interface to several observatories for which observations can be requested. Requesting Observations -^^^^^^^^^^^^^^^^^^^^^^^ +----------------------- Using the TOM Observation module, scientists can request observations of their targets to one or many different observatories. Since the @@ -61,7 +61,7 @@ programs. .. image:: /_static/common_interface.png Observation Status -^^^^^^^^^^^^^^^^^^ +------------------ Once an observation for a target is created it’s status is kept up to date within the TOM. When the status of an observation request at an @@ -69,7 +69,7 @@ observatory changes (failed, completed, postponed, etc) the scientist may be notified by the TOM. Data -~~~~ +---- The ultimate goal of the TOM toolkit is to collect and organize data. The TOM data module provides several methods for obtaining data, the @@ -77,7 +77,7 @@ most obvious being from completed observations. Scientists can also upload any data they’d like to associate with their targets as well. Data Processing -^^^^^^^^^^^^^^^ +--------------- The TOM toolkit provides a framework to write custom code to interact with the data the TOM obtains (among other things). These are called @@ -88,7 +88,7 @@ images of microlensed stars for exoplanets, they may hook the code into the TOM toolkit directly to run whenever new data is acquired. Downloading Data -^^^^^^^^^^^^^^^^ +---------------- Data is stored in the TOM toolkit by default, but many scientists may want to download the data somewhere else to do offline processing. diff --git a/docs/managing_data/index.rst b/docs/managing_data/index.rst index ad3b4ebdf..c85eaa0f9 100644 --- a/docs/managing_data/index.rst +++ b/docs/managing_data/index.rst @@ -1,31 +1,68 @@ Managing Data ============= -.. toctree:: - :maxdepth: 2 - :hidden: +The TOM's Data Models +--------------------- +The TOM Toolkit includes two distinct models for data in the ``tom_dataproducts`` module: - ../api/tom_dataproducts/views - plotting_data - customizing_data_processing - tom_direct_sharing - stream_pub_sub - continuous_sharing - single_target_data_service +* ``DataProduct``: Corresponds to any file containing data, from a FITS, to a PNG, to a CSV. It can optionally be + associated with a specific observation, and is required to be associated with a target. A ``DataProduct`` can have a + specified type which can be used to trigger post-save hooks to perform automated process upon ingest. +* ``ReducedDatum``: Refers to a single piece of data - e.g., a spectrum, a single measurement or a set of timeseries + photometry measurements. It is associated with a target, and optionally with the data product it came from. +The TOM also allows a ``DataProductGroup`` to be defined. This allows TOM administrators control over which user +groups can access which data products. -:doc:`Creating Plots from TOM Data ` - Learn how to create plots using plot.ly and your TOM -data to display anywhere in your TOM. +Ingesting data into the TOM +--------------------------- +Data products for a given target can be uploaded through the ``Manage Data`` tab on the target's detail page, or +programmatically. -:doc:`Adding Custom Data Processing ` - Learn how you can process data into your -TOM from uploaded data products. +.. figure:: /_static/managing_data/data_upload_form.png + :alt: TOM's data upload form + :width: 100% + :align: center -:doc:`TOM-TOM Direct Sharing ` - Learn how you can send and receive data between your TOM and another TOM-Toolkit TOM via an API. + DataProduct upload form in the TOM's target detail page -:doc:`Publish and Subscribe to a Kafka Stream ` - Learn how to publish and subscribe to a Kafka stream topic. +If a data product type is specified, then the TOM calls uses post-save hooks to call the corresponding built-in +processing functions found in ``tom_dataproducts/processors``. The TOM's ``photometry_processor.py`` for example, +reads a photometry data file and ingests the timeseries measurements as ``ReducedDatum``. -:doc:`Setting up Continuous Sharing of a target's data to a TOM or Kafka stream ` - Learn how to set up continuous sharing of a Target's data products. +It's also possible for users to add their own custom data formats and corresponding specialized processors - see +:doc:`Adding Custom Data Processing ` for more details. -:doc:`Integrating Single-Target Data Service Queries ` - Learn how to integrate the existing Atlas, panSTARRS, and ZTF -single-target data services into your TOM, and learn how to add new services. +Data Visualization +------------------ + +The Toolkit includes built-in interactive tools for plotting data types common in astronomy, such as +light curves and spectra. But it is often useful to customize these for particular science goals. +:doc:`Creating Plots from TOM Data ` describes how to create interactive plots of your data +to display anywhere in your TOM. + +Data Sharing +------------ + +Many users find it valuable to be able to share data from their TOM system with other people, services or directly with +other TOM systems. The Toolkit includes a number of different data sharing options: + +* :doc:`TOM-TOM Direct Sharing ` - Send and receive data between your TOM and another TOM-Toolkit TOM via an API. + +* :doc:`Publish and Subscribe to a Kafka Stream ` - Publish and subscribe to a Kafka stream topic. + +* :doc:`Setting up Continuous Sharing of a target's data to a TOM or Kafka stream ` - Set up continuous sharing of a Target's data products. + +Survey data on a Target +----------------------- + +Archival data can be a valuable resource for understanding its nature and behaviour. These include data archives, which +hold source catalogs, photometry, spectroscopy and imaging data in many wavelengths, as well as forced photometry +services. These are offered by a number of surveys, to enable users to search for precursor observations. + +The TOM include a number of built-in single-target data service query functions to allow the user to harvest data +for a given object from surveys including ATLAS and Pan-STARRS. + +To learn about these functions, and how to add a new service to your TOM, see +:doc:`Integrating Single-Target Data Service Queries `. diff --git a/docs/managing_data/single_target_data_service.rst b/docs/managing_data/single_target_data_service.rst index dbf86f71c..fb806683e 100644 --- a/docs/managing_data/single_target_data_service.rst +++ b/docs/managing_data/single_target_data_service.rst @@ -6,8 +6,7 @@ The base TOM Toolkit comes with `ATLAS `). +Additional services can be added by extending the ``BaseSingleTargetDataService`` implementation. Integrating existing Single-Target Data Services diff --git a/docs/observing/index.rst b/docs/observing/index.rst index 3ac917ba8..e4713e7ec 100644 --- a/docs/observing/index.rst +++ b/docs/observing/index.rst @@ -1,36 +1,130 @@ Observing Facilities and Observations ===================================== -.. toctree:: - :maxdepth: 2 - :hidden: +One of a TOM's most powerful features is to enable astronomers to directly request observations from telescope facilities. +With this capability becoming more and more common among observatories, TOMs can be used to easily coordinate observations +across a number of telescopes. Observing programs can also scripted, so that the TOM can automatically observe +targets selected according to pre-defined criteria and with observations determined by a pre-defined strategy. - customize_ocs_facility - ../common/scripts - strategies - observation_module - selecting_targets_for_facility - ../api/tom_observations/models - ../api/tom_observations/facilities - ../api/tom_observations/views +Built-in Observing Facilities +----------------------------- +The TOM includes built-in modules that provide interfaces to a number of telescopes including: -:doc:`Customizing an OCS Facility and its Forms ` - Learn how to customize an -`Observatory Control System `_ facility and its observation forms -to add new fields and behaviour. +* `Las Cumbres Observatory 0.4m, 1m and 2m telescope networks `_ +* `4.1m Southern Astrophysical Research (SOAR) Telescope `_ +* `8m Gemini Telescopes North and South `_ +* `4m Víctor M. Blanco Telescope `_ -`Programmatically Submitting Observations <../common/scripts.html#creating-observations-programmatically>`__ +These modules enable users to compose and submit requests for observations, and to calculate target visibility from +these observing sites. Data products resulting from submitted observations can also be retrieved. -:doc:`Cadence and Observing Strategies ` - Learn how to build cadence strategies that submit observations based on -the result of prior observations, as well as how to leverage observing templates to submit observations with fewer clicks. +Detailed information on these modules can be found here: +:doc:`Facility Modules <../api/tom_observations/facilities>` - Take a look at the supported facilities. -:doc:`Building a TOM Observation Facility Module ` - Learn to build a module which will -allow your TOM to submit observation requests to observatories. +:doc:`Observation Views <../api/tom_observations/views>` - Familiarize yourself with the available Observation Views. -:doc:`Selecting Targets ` - Display a selection of targets for a specific observing facility. -:doc:`Observation Models <../api/tom_observations/models>` - Learn about the models used to store observation data. +Additional Telescope Facilities +------------------------------- -:doc:`Facility Modules <../api/tom_observations/facilities>` - Take a look at the supported facilities. +The Toolkit also has a number of optional plugin modules providing interfaces to other telescopes, including: -:doc:`Observation Views <../api/tom_observations/views>` - Familiarize yourself with the available Observation Views. +* `2m Liverpool Telescope `_ +* `Telescopes at the European Southern Observatory `_ +* `Neil Gehrels Swift Observatory `_ + +For more information about the plugin modules, see :doc:`Plugins `. + +Facilities Table +---------------- + +The TOM's ``tom_observations`` module also has a database table (model) for telescope facilities where users can store +general information about telescopes, including the location of the telescope site(s) or orbits, wavelength range, etc, +regardless of whether they can accept the programmatic submission of observations. +This enables the TOM to include these facilties, for example when calculating target visibility. + +A TOM administrator can add facilities to this table using the TOM's admin interface. + +Adding Telescope Modules to the TOM +----------------------------------- + +Modules can be added to enable the submission of observations to additional telescope facilities. +For telescopes using LCO's `Observatory Control System `_ software, +:doc:`Customizing an OCS Facility and its Forms ` describes how to customize the facility and +its observation forms to add new fields and behaviour. + +:doc:`Building a TOM Observation Facility Module ` describes how to build a module for any telescope +that allows the programmatic submission of observations. + +We encourage users with custom telescope module to submit a pull request through Github to the TOM Toolkit, to share +the capability with other users. + +Making Observations Interactively +--------------------------------- + +Requests for observations on multiple telescopes for can be submitted interactively from the detail page of an individual ``Target``. +This can be done by clicking on the button for the desired observatory under the ``observe`` tab: + +.. figure:: /_static/observation_module/target_detail_observe_buttons.png + :alt: Section of a target detail page showing the buttons to submit observations + :width: 100% + :align: center + + Observatory buttons under the `observe` tab of a target detail page. + +Each button takes the user to the observation request form for the corresponding telescope's instrumentation. + +Automating your observations +---------------------------- + +It's also possible to request observations programmatically, through a script. This can be a very powerful +way to orchestrate an observing program, and allows users to automate their observations. An example of +this approach can be found under +:doc:`Programmatically Submitting Observations `. + +Observing Strategies and Templates +---------------------------------- + +A further step in automating your observing program is to tell the TOM what your strategy is for future observations +of a given target. For example, this allows it to automatically re-submit a previously-defined observation request in +the event that those observations were not executed for whatever reason. + +:doc:`Cadence and Observing Strategies ` describes how to build cadence strategies that submit observations +based on the result of prior observations, as well as how to leverage observing templates to submit observations +with fewer clicks. + + +Finding visible targets +----------------------- + +Identifying which targets are visible from a given observatory is a routine task in any observing program. The TOM's +target detail page includes a tool that computes the target's visibility from a range of different sites. + +.. grid:: 2 + :gutter: 3 + + .. grid-item:: + .. figure:: /_static/observation_module/target_visibility_tool.png + :width: 100% + + Target visibility calculator + + .. grid-item:: + .. figure:: /_static/observation_module/target_moon_separation_plot.png + :width: 100% + + Plot of target separation from the Moon + +Conversely, the TOM also has a tool to figure out which of your targets will be visible from a given telescopes. +This is described under :doc:`Selecting Targets `. + +Observation Records +------------------- + +The TOM keeps an ``Observation_Record`` of all observations submitted through it, either interactively or programmatically. +These records include the parameters of the observation request and its status of execution. +For observatories that offer APIs to allow users to query observation status, the TOM includes tools to update +this parameter programmatically. + +For more details about observation-related models in the TOM see :doc:`Observation Models `. diff --git a/docs/targets/index.rst b/docs/targets/index.rst index 905a8bc99..eb09b3cc6 100644 --- a/docs/targets/index.rst +++ b/docs/targets/index.rst @@ -1,33 +1,54 @@ Targets ======= -.. toctree:: - :maxdepth: 2 - :hidden: +The ``Target``, along with the associated ``TargetList``, ``TargetExtra``, and ``TargetName``, are the core models of the +TOM Toolkit. The ``Target`` defines the concept of an astronomical target through a number of parameters. The ``Target`` +object is then used throughout the TOM to reference all the +information a user or app needs to know about a target. As astrophysical objects are often identified in multiple catalogs, +each ``Target`` is associated with one or more ``TargetName``s. - target_fields - target_matcher - target_table - ../api/tom_targets/models - ../api/tom_targets/views - ../api/tom_targets/groups +More information on Targets can be found using the following pages: +:doc:`Target Models ` - Take a look at the available properties for a ``Target`` and its associated models. -The ``Target``, along with the associated ``TargetList``, ``TargetExtra``, and ``TargetName``, are the core models of the -TOM Toolkit. The ``Target`` defines the concept of an astronomical target through a number of parameters. This -object is then used throughout the TOM to reference all the information a user or app needs to know about a target. -More information on Targets can be found using the following pages: +:doc:`Target Views ` - Familiarize yourself with the available Target Views. + +:doc:`Target Lists ` - Check out the functions for operating on Target Lists/Target Groups. + + +Customizing the BaseTarget +-------------------------- + +Although almost all astrophysical targets share some descriptive parameters - such as RA, Dec or orbital parameters - +the Toolkit recognises that each science case has a specific set of relevant parameters. For example, for some science +goals, a ``Target`` may have a measured period, while this may not be appropriate for an aperiodic object. + +For this reason, the Toolkit provides a ``BaseTarget`` class which supports both sidereal and non-sidereal celestial objects. +By default, this is used to create the ``Target`` model when a TOM is created. +However, this class is designed to be extended by users to add fields relevant to their science. See +:doc:`Adding Custom Target Fields ` to learn how to add custom fields to your TOM Targets. + +Crossmatching Targets +--------------------- -:doc:`Adding Custom Target Fields ` - Learn how to add custom fields to your TOM Targets if the -defaults do not suffice. +It is often useful to compare a target with those already in the TOM, especially to avoid duplicating targets. +By default, matching is performed on ``TargetName``, but the TOM includes functions to match on position as well. +If you need to compare targets using different parameters, :doc:`Customizing a Target Matcher ` +describes how to add a custom match function. -:doc:`Customizing a Target Matcher ` - Learn how to replace or modify the TargetMatchManager if more -options are needed. +TargetLists +----------- -:doc:`Customizing the Target List Table ` - Learn how to modify which columns are displayed in the target list table. +By default, all targets in the TOM are treated as a single collection, which can be viewed as a table and on an +interactive skymap by navigating to the Targets view. +The columns presented in the target list table can be customized - see :doc:`Customizing the Target List Table ` +for more information. -:doc:`Target Models <../api/tom_targets/models>` - Take a look at the available properties for a ``Target`` and its associated models. +Targets can be collected into user-created lists for convenience. -:doc:`Target Views <../api/tom_targets/views>` - Familiarize yourself with the available Target Views. +Target and TargetList Sharing +----------------------------- -:doc:`Target Lists <../api/tom_targets/groups>` - Check out the functions for operating on Target Lists/Target Groups. +Individual targets and their associated data can be shared directly with another TOM, with the TOM administrator's +permission. Sets of targets can also be shared. See :doc:`TOM Direct Sharing ` +to learn how to configure the TOMs to allow this. \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 1abad98f5..32b0fc348 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,15 +1,34 @@ -# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. + +[[package]] +name = "accessible-pygments" +version = "0.0.5" +description = "A collection of accessible pygments styles" +optional = false +python-versions = ">=3.9" +groups = ["docs"] +files = [ + {file = "accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7"}, + {file = "accessible_pygments-0.0.5.tar.gz", hash = "sha256:40918d3e6a2b619ad424cb91e556bd3bd8865443d9f22f1dcdf79e33c8046872"}, +] + +[package.dependencies] +pygments = ">=1.5" + +[package.extras] +dev = ["pillow", "pkginfo (>=1.10)", "playwright", "pre-commit", "setuptools", "twine (>=5.0)"] +tests = ["hypothesis", "pytest"] [[package]] name = "alabaster" -version = "0.7.16" +version = "1.0.0" description = "A light, configurable Sphinx theme" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["docs"] files = [ - {file = "alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92"}, - {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, + {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}, + {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}, ] [[package]] @@ -253,14 +272,14 @@ typing = ["typing_extensions (>=4.0.0)"] [[package]] name = "astropy-iers-data" -version = "0.2026.4.27.1.3.2" +version = "0.2026.5.4.1.4.54" description = "IERS Earth Rotation and Leap Second tables for the astropy core package" optional = false python-versions = ">=3.10" groups = ["main"] files = [ - {file = "astropy_iers_data-0.2026.4.27.1.3.2-py3-none-any.whl", hash = "sha256:3c09006b1b7c369a4dd9ba7e395b04cbfedb41a9253013b3bf7e5b8ac53a7699"}, - {file = "astropy_iers_data-0.2026.4.27.1.3.2.tar.gz", hash = "sha256:fc71b5b2e601afb1b8c4f22a35161c551d67469ec65502123591dae6a87d453b"}, + {file = "astropy_iers_data-0.2026.5.4.1.4.54-py3-none-any.whl", hash = "sha256:9d9014f530020fec2da8de29d5ada776b95cf3616cfac41311853f9f753d1928"}, + {file = "astropy_iers_data-0.2026.5.4.1.4.54.tar.gz", hash = "sha256:74b70c810e430c274ff9f0c91680d56f7703add8c367c842902dd53130f70832"}, ] [package.extras] @@ -343,7 +362,7 @@ version = "4.14.3" description = "Screen-scraping library" optional = false python-versions = ">=3.7.0" -groups = ["main"] +groups = ["main", "docs"] files = [ {file = "beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb"}, {file = "beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86"}, @@ -638,19 +657,81 @@ files = [ markers = {coverage = "platform_system == \"Windows\"", docs = "sys_platform == \"win32\""} [[package]] -name = "commonmark" -version = "0.9.1" -description = "Python parser for the CommonMark Markdown spec" +name = "contourpy" +version = "1.3.2" +description = "Python library for calculating contours of 2D quadrilateral grids" optional = false -python-versions = "*" +python-versions = ">=3.10" groups = ["docs"] files = [ - {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, - {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, + {file = "contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934"}, + {file = "contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989"}, + {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d"}, + {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9"}, + {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512"}, + {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631"}, + {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f"}, + {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2"}, + {file = "contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0"}, + {file = "contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a"}, + {file = "contourpy-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445"}, + {file = "contourpy-1.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773"}, + {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1"}, + {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43"}, + {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab"}, + {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7"}, + {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83"}, + {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd"}, + {file = "contourpy-1.3.2-cp311-cp311-win32.whl", hash = "sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f"}, + {file = "contourpy-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878"}, + {file = "contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2"}, + {file = "contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15"}, + {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92"}, + {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87"}, + {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415"}, + {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe"}, + {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441"}, + {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e"}, + {file = "contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912"}, + {file = "contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73"}, + {file = "contourpy-1.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de39db2604ae755316cb5967728f4bea92685884b1e767b7c24e983ef5f771cb"}, + {file = "contourpy-1.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f9e896f447c5c8618f1edb2bafa9a4030f22a575ec418ad70611450720b5b08"}, + {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71e2bd4a1c4188f5c2b8d274da78faab884b59df20df63c34f74aa1813c4427c"}, + {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de425af81b6cea33101ae95ece1f696af39446db9682a0b56daaa48cfc29f38f"}, + {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:977e98a0e0480d3fe292246417239d2d45435904afd6d7332d8455981c408b85"}, + {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:434f0adf84911c924519d2b08fc10491dd282b20bdd3fa8f60fd816ea0b48841"}, + {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c66c4906cdbc50e9cba65978823e6e00b45682eb09adbb78c9775b74eb222422"}, + {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8b7fc0cd78ba2f4695fd0a6ad81a19e7e3ab825c31b577f384aa9d7817dc3bef"}, + {file = "contourpy-1.3.2-cp313-cp313-win32.whl", hash = "sha256:15ce6ab60957ca74cff444fe66d9045c1fd3e92c8936894ebd1f3eef2fff075f"}, + {file = "contourpy-1.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1578f7eafce927b168752ed7e22646dad6cd9bca673c60bff55889fa236ebf9"}, + {file = "contourpy-1.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0475b1f6604896bc7c53bb070e355e9321e1bc0d381735421a2d2068ec56531f"}, + {file = "contourpy-1.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c85bb486e9be652314bb5b9e2e3b0d1b2e643d5eec4992c0fbe8ac71775da739"}, + {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:745b57db7758f3ffc05a10254edd3182a2a83402a89c00957a8e8a22f5582823"}, + {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:970e9173dbd7eba9b4e01aab19215a48ee5dd3f43cef736eebde064a171f89a5"}, + {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c4639a9c22230276b7bffb6a850dfc8258a2521305e1faefe804d006b2e532"}, + {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc829960f34ba36aad4302e78eabf3ef16a3a100863f0d4eeddf30e8a485a03b"}, + {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d32530b534e986374fc19eaa77fcb87e8a99e5431499949b828312bdcd20ac52"}, + {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e298e7e70cf4eb179cc1077be1c725b5fd131ebc81181bf0c03525c8abc297fd"}, + {file = "contourpy-1.3.2-cp313-cp313t-win32.whl", hash = "sha256:d0e589ae0d55204991450bb5c23f571c64fe43adaa53f93fc902a84c96f52fe1"}, + {file = "contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69"}, + {file = "contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c"}, + {file = "contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16"}, + {file = "contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad"}, + {file = "contourpy-1.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0"}, + {file = "contourpy-1.3.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5"}, + {file = "contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5"}, + {file = "contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54"}, ] +[package.dependencies] +numpy = ">=1.23" + [package.extras] -test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.15.0)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] [[package]] name = "coverage" @@ -876,16 +957,32 @@ typing-extensions = {version = ">=4.13.2", markers = "python_full_version < \"3. [package.extras] ssh = ["bcrypt (>=3.1.5)"] +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "django" -version = "5.2.13" +version = "5.2.14" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.10" groups = ["main"] files = [ - {file = "django-5.2.13-py3-none-any.whl", hash = "sha256:5788fce61da23788a8ce6f02583765ab060d396720924789f97fa42119d37f7a"}, - {file = "django-5.2.13.tar.gz", hash = "sha256:a31589db5188d074c63f0945c3888fad104627dfcc236fb2b97f71f89da33bc4"}, + {file = "django-5.2.14-py3-none-any.whl", hash = "sha256:6f712143bd3064310d1f50fac859c3e9a274bdcfc9595339853be7779297fc76"}, + {file = "django-5.2.14.tar.gz", hash = "sha256:58a63ba841662e5c686b57ba1fec52ddd68c0b93bd96ac3029d55728f00bf8a2"}, ] [package.dependencies] @@ -1099,6 +1196,21 @@ files = [ {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, ] +[[package]] +name = "emoji" +version = "2.15.0" +description = "Emoji for Python" +optional = false +python-versions = ">=3.8" +groups = ["docs"] +files = [ + {file = "emoji-2.15.0-py3-none-any.whl", hash = "sha256:205296793d66a89d88af4688fa57fd6496732eb48917a87175a023c8138995eb"}, + {file = "emoji-2.15.0.tar.gz", hash = "sha256:eae4ab7d86456a70a00a985125a03263a5eac54cd55e51d7e184b1ed3b6757e4"}, +] + +[package.extras] +dev = ["coverage", "pytest (>=7.4.4)"] + [[package]] name = "factory-boy" version = "3.3.3" @@ -1170,6 +1282,79 @@ mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.14.0,<2.15.0" pyflakes = ">=3.4.0,<3.5.0" +[[package]] +name = "fonttools" +version = "4.62.1" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.10" +groups = ["docs"] +files = [ + {file = "fonttools-4.62.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ad5cca75776cd453b1b035b530e943334957ae152a36a88a320e779d61fc980c"}, + {file = "fonttools-4.62.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b3ae47e8636156a9accff64c02c0924cbebad62854c4a6dbdc110cd5b4b341a"}, + {file = "fonttools-4.62.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b9e288b4da2f64fd6180644221749de651703e8d0c16bd4b719533a3a7d6e3"}, + {file = "fonttools-4.62.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7bca7a1c1faf235ffe25d4f2e555246b4750220b38de8261d94ebc5ce8a23c23"}, + {file = "fonttools-4.62.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b4e0fcf265ad26e487c56cb12a42dffe7162de708762db951e1b3f755319507d"}, + {file = "fonttools-4.62.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2d850f66830a27b0d498ee05adb13a3781637b1826982cd7e2b3789ef0cc71ae"}, + {file = "fonttools-4.62.1-cp310-cp310-win32.whl", hash = "sha256:486f32c8047ccd05652aba17e4a8819a3a9d78570eb8a0e3b4503142947880ed"}, + {file = "fonttools-4.62.1-cp310-cp310-win_amd64.whl", hash = "sha256:5a648bde915fba9da05ae98856987ca91ba832949a9e2888b48c47ef8b96c5a9"}, + {file = "fonttools-4.62.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:40975849bac44fb0b9253d77420c6d8b523ac4dcdcefeff6e4d706838a5b80f7"}, + {file = "fonttools-4.62.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9dde91633f77fa576879a0c76b1d89de373cae751a98ddf0109d54e173b40f14"}, + {file = "fonttools-4.62.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6acb4109f8bee00fec985c8c7afb02299e35e9c94b57287f3ea542f28bd0b0a7"}, + {file = "fonttools-4.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1c5c25671ce8805e0d080e2ffdeca7f1e86778c5cbfbeae86d7f866d8830517b"}, + {file = "fonttools-4.62.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a5d8825e1140f04e6c99bb7d37a9e31c172f3bc208afbe02175339e699c710e1"}, + {file = "fonttools-4.62.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:268abb1cb221e66c014acc234e872b7870d8b5d4657a83a8f4205094c32d2416"}, + {file = "fonttools-4.62.1-cp311-cp311-win32.whl", hash = "sha256:942b03094d7edbb99bdf1ae7e9090898cad7bf9030b3d21f33d7072dbcb51a53"}, + {file = "fonttools-4.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:e8514f4924375f77084e81467e63238b095abda5107620f49421c368a6017ed2"}, + {file = "fonttools-4.62.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:90365821debbd7db678809c7491ca4acd1e0779b9624cdc6ddaf1f31992bf974"}, + {file = "fonttools-4.62.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12859ff0b47dd20f110804c3e0d0970f7b832f561630cd879969011541a464a9"}, + {file = "fonttools-4.62.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c125ffa00c3d9003cdaaf7f2c79e6e535628093e14b5de1dccb08859b680936"}, + {file = "fonttools-4.62.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:149f7d84afca659d1a97e39a4778794a2f83bf344c5ee5134e09995086cc2392"}, + {file = "fonttools-4.62.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0aa72c43a601cfa9273bb1ae0518f1acadc01ee181a6fc60cd758d7fdadffc04"}, + {file = "fonttools-4.62.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:19177c8d96c7c36359266e571c5173bcee9157b59cfc8cb0153c5673dc5a3a7d"}, + {file = "fonttools-4.62.1-cp312-cp312-win32.whl", hash = "sha256:a24decd24d60744ee8b4679d38e88b8303d86772053afc29b19d23bb8207803c"}, + {file = "fonttools-4.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:9e7863e10b3de72376280b515d35b14f5eeed639d1aa7824f4cf06779ec65e42"}, + {file = "fonttools-4.62.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c22b1014017111c401469e3acc5433e6acf6ebcc6aa9efb538a533c800971c79"}, + {file = "fonttools-4.62.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:68959f5fc58ed4599b44aad161c2837477d7f35f5f79402d97439974faebfebe"}, + {file = "fonttools-4.62.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef46db46c9447103b8f3ff91e8ba009d5fe181b1920a83757a5762551e32bb68"}, + {file = "fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1"}, + {file = "fonttools-4.62.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e7abd2b1e11736f58c1de27819e1955a53267c21732e78243fa2fa2e5c1e069"}, + {file = "fonttools-4.62.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:403d28ce06ebfc547fbcb0cb8b7f7cc2f7a2d3e1a67ba9a34b14632df9e080f9"}, + {file = "fonttools-4.62.1-cp313-cp313-win32.whl", hash = "sha256:93c316e0f5301b2adbe6a5f658634307c096fd5aae60a5b3412e4f3e1728ab24"}, + {file = "fonttools-4.62.1-cp313-cp313-win_amd64.whl", hash = "sha256:7aa21ff53e28a9c2157acbc44e5b401149d3c9178107130e82d74ceb500e5056"}, + {file = "fonttools-4.62.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fa1d16210b6b10a826d71bed68dd9ec24a9e218d5a5e2797f37c573e7ec215ca"}, + {file = "fonttools-4.62.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aa69d10ed420d8121118e628ad47d86e4caa79ba37f968597b958f6cceab7eca"}, + {file = "fonttools-4.62.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd13b7999d59c5eb1c2b442eb2d0c427cb517a0b7a1f5798fc5c9e003f5ff782"}, + {file = "fonttools-4.62.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8d337fdd49a79b0d51c4da87bc38169d21c3abbf0c1aa9367eff5c6656fb6dae"}, + {file = "fonttools-4.62.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d241cdc4a67b5431c6d7f115fdf63335222414995e3a1df1a41e1182acd4bcc7"}, + {file = "fonttools-4.62.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c05557a78f8fa514da0f869556eeda40887a8abc77c76ee3f74cf241778afd5a"}, + {file = "fonttools-4.62.1-cp314-cp314-win32.whl", hash = "sha256:49a445d2f544ce4a69338694cad575ba97b9a75fff02720da0882d1a73f12800"}, + {file = "fonttools-4.62.1-cp314-cp314-win_amd64.whl", hash = "sha256:1eecc128c86c552fb963fe846ca4e011b1be053728f798185a1687502f6d398e"}, + {file = "fonttools-4.62.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:1596aeaddf7f78e21e68293c011316a25267b3effdaccaf4d59bc9159d681b82"}, + {file = "fonttools-4.62.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8f8fca95d3bb3208f59626a4b0ea6e526ee51f5a8ad5d91821c165903e8d9260"}, + {file = "fonttools-4.62.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee91628c08e76f77b533d65feb3fbe6d9dad699f95be51cf0d022db94089cdc4"}, + {file = "fonttools-4.62.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5f37df1cac61d906e7b836abe356bc2f34c99d4477467755c216b72aa3dc748b"}, + {file = "fonttools-4.62.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:92bb00a947e666169c99b43753c4305fc95a890a60ef3aeb2a6963e07902cc87"}, + {file = "fonttools-4.62.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:bdfe592802ef939a0e33106ea4a318eeb17822c7ee168c290273cbd5fabd746c"}, + {file = "fonttools-4.62.1-cp314-cp314t-win32.whl", hash = "sha256:b820fcb92d4655513d8402d5b219f94481c4443d825b4372c75a2072aa4b357a"}, + {file = "fonttools-4.62.1-cp314-cp314t-win_amd64.whl", hash = "sha256:59b372b4f0e113d3746b88985f1c796e7bf830dd54b28374cd85c2b8acd7583e"}, + {file = "fonttools-4.62.1-py3-none-any.whl", hash = "sha256:7487782e2113861f4ddcc07c3436450659e3caa5e470b27dc2177cade2d8e7fd"}, + {file = "fonttools-4.62.1.tar.gz", hash = "sha256:e54c75fd6041f1122476776880f7c3c3295ffa31962dc6ebe2543c00dca58b5d"}, +] + +[package.extras] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.45.0)", "unicodedata2 (>=17.0.0) ; python_version <= \"3.14\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.45.0)"] +symfont = ["sympy"] +type1 = ["xattr ; sys_platform == \"darwin\""] +unicode = ["unicodedata2 (>=17.0.0) ; python_version <= \"3.14\""] +woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] + [[package]] name = "gwcs" version = "0.24.0" @@ -1430,6 +1615,133 @@ enabler = ["pytest-enabler (>=3.4)"] test = ["pyfakefs", "pytest (>=6,!=8.1.*)"] type = ["pygobject-stubs", "pytest-mypy (>=1.0.1)", "shtab", "types-pywin32"] +[[package]] +name = "kiwisolver" +version = "1.5.0" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.10" +groups = ["docs"] +files = [ + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374"}, + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd"}, + {file = "kiwisolver-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e"}, + {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c"}, + {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede"}, + {file = "kiwisolver-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2"}, + {file = "kiwisolver-1.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb"}, + {file = "kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc"}, + {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08"}, + {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4"}, + {file = "kiwisolver-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b"}, + {file = "kiwisolver-1.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588"}, + {file = "kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083"}, + {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314"}, + {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9"}, + {file = "kiwisolver-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384"}, + {file = "kiwisolver-1.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3"}, + {file = "kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8"}, + {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167"}, + {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0"}, + {file = "kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276"}, + {file = "kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2"}, + {file = "kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02"}, + {file = "kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a"}, + {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79"}, + {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796"}, + {file = "kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e"}, + {file = "kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681"}, + {file = "kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7"}, + {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed"}, + {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16"}, + {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1"}, + {file = "kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a"}, +] + [[package]] name = "markdown" version = "3.10.2" @@ -1448,14 +1760,14 @@ testing = ["coverage", "pyyaml"] [[package]] name = "markdown-it-py" -version = "4.0.0" +version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false -python-versions = ">=3.10" -groups = ["coverage"] +python-versions = ">=3.8" +groups = ["coverage", "docs"] files = [ - {file = "markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147"}, - {file = "markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3"}, + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] [package.dependencies] @@ -1463,12 +1775,13 @@ mdurl = ">=0.1,<1.0" [package.extras] benchmarking = ["psutil", "pytest", "pytest-benchmark"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "markdown-it-pyrs", "mistletoe (>=1.0,<2.0)", "mistune (>=3.0,<4.0)", "panflute (>=2.3,<3.0)"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins (>=0.5.0)"] +plugins = ["mdit-py-plugins"] profiling = ["gprof2dot"] -rtd = ["ipykernel", "jupyter_sphinx", "mdit-py-plugins (>=0.5.0)", "myst-parser", "pyyaml", "sphinx", "sphinx-book-theme (>=1.0,<2.0)", "sphinx-copybutton", "sphinx-design"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "requests"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" @@ -1569,6 +1882,85 @@ files = [ {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"}, ] +[[package]] +name = "matplotlib" +version = "3.10.9" +description = "Python plotting package" +optional = false +python-versions = ">=3.10" +groups = ["docs"] +files = [ + {file = "matplotlib-3.10.9-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217"}, + {file = "matplotlib-3.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b"}, + {file = "matplotlib-3.10.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37"}, + {file = "matplotlib-3.10.9-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294"}, + {file = "matplotlib-3.10.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65"}, + {file = "matplotlib-3.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda"}, + {file = "matplotlib-3.10.9-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb"}, + {file = "matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb"}, + {file = "matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb"}, + {file = "matplotlib-3.10.9-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9"}, + {file = "matplotlib-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb"}, + {file = "matplotlib-3.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f"}, + {file = "matplotlib-3.10.9-cp311-cp311-win_arm64.whl", hash = "sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80"}, + {file = "matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1"}, + {file = "matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320"}, + {file = "matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285"}, + {file = "matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2"}, + {file = "matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf"}, + {file = "matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6"}, + {file = "matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42"}, + {file = "matplotlib-3.10.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f"}, + {file = "matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e"}, + {file = "matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f"}, + {file = "matplotlib-3.10.9-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838"}, + {file = "matplotlib-3.10.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2"}, + {file = "matplotlib-3.10.9-cp313-cp313-win_amd64.whl", hash = "sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921"}, + {file = "matplotlib-3.10.9-cp313-cp313-win_arm64.whl", hash = "sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8"}, + {file = "matplotlib-3.10.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9"}, + {file = "matplotlib-3.10.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4"}, + {file = "matplotlib-3.10.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc"}, + {file = "matplotlib-3.10.9-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99"}, + {file = "matplotlib-3.10.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d"}, + {file = "matplotlib-3.10.9-cp313-cp313t-win_amd64.whl", hash = "sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8"}, + {file = "matplotlib-3.10.9-cp313-cp313t-win_arm64.whl", hash = "sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38"}, + {file = "matplotlib-3.10.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d"}, + {file = "matplotlib-3.10.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f"}, + {file = "matplotlib-3.10.9-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b"}, + {file = "matplotlib-3.10.9-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2"}, + {file = "matplotlib-3.10.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716"}, + {file = "matplotlib-3.10.9-cp314-cp314-win_amd64.whl", hash = "sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f"}, + {file = "matplotlib-3.10.9-cp314-cp314-win_arm64.whl", hash = "sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456"}, + {file = "matplotlib-3.10.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe"}, + {file = "matplotlib-3.10.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6"}, + {file = "matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c"}, + {file = "matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4"}, + {file = "matplotlib-3.10.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf"}, + {file = "matplotlib-3.10.9-cp314-cp314t-win_amd64.whl", hash = "sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39"}, + {file = "matplotlib-3.10.9-cp314-cp314t-win_arm64.whl", hash = "sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c"}, + {file = "matplotlib-3.10.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b"}, + {file = "matplotlib-3.10.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f"}, + {file = "matplotlib-3.10.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585"}, + {file = "matplotlib-3.10.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20"}, + {file = "matplotlib-3.10.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba"}, + {file = "matplotlib-3.10.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4"}, + {file = "matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=3" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7,<10)"] + [[package]] name = "mccabe" version = "0.7.0" @@ -1581,13 +1973,33 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mdit-py-plugins" +version = "0.5.0" +description = "Collection of plugins for markdown-it-py" +optional = false +python-versions = ">=3.10" +groups = ["docs"] +files = [ + {file = "mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f"}, + {file = "mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6"}, +] + +[package.dependencies] +markdown-it-py = ">=2.0.0,<5.0.0" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["myst-parser", "sphinx-book-theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" -groups = ["coverage"] +groups = ["coverage", "docs"] files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, @@ -1605,6 +2017,33 @@ files = [ {file = "more_itertools-11.0.2.tar.gz", hash = "sha256:392a9e1e362cbc106a2457d37cabf9b36e5e12efd4ebff1654630e76597df804"}, ] +[[package]] +name = "myst-parser" +version = "4.0.1" +description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," +optional = false +python-versions = ">=3.10" +groups = ["docs"] +files = [ + {file = "myst_parser-4.0.1-py3-none-any.whl", hash = "sha256:9134e88959ec3b5780aedf8a99680ea242869d012e8821db3126d427edc9c95d"}, + {file = "myst_parser-4.0.1.tar.gz", hash = "sha256:5cfea715e4f3574138aecbf7d54132296bfd72bb614d31168f48c477a830a7c4"}, +] + +[package.dependencies] +docutils = ">=0.19,<0.22" +jinja2 = "*" +markdown-it-py = ">=3.0,<4.0" +mdit-py-plugins = ">=0.4.1,<1.0" +pyyaml = "*" +sphinx = ">=7,<9" + +[package.extras] +code-style = ["pre-commit (>=4.0,<5.0)"] +linkify = ["linkify-it-py (>=2.0,<3.0)"] +rtd = ["ipython", "sphinx (>=7)", "sphinx-autodoc2 (>=0.5.0,<0.6.0)", "sphinx-book-theme (>=1.1,<2.0)", "sphinx-copybutton", "sphinx-design", "sphinx-pyscript", "sphinx-tippy (>=0.4.3)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.9.0,<0.10.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] +testing = ["beautifulsoup4", "coverage[toml]", "defusedxml", "pygments (<2.19)", "pytest (>=8,<9)", "pytest-cov", "pytest-param-files (>=0.6.0,<0.7.0)", "pytest-regressions", "sphinx-pytest"] +testing-docutils = ["pygments", "pytest (>=8,<9)", "pytest-param-files (>=0.6.0,<0.7.0)"] + [[package]] name = "ndcube" version = "2.3.5" @@ -1637,7 +2076,7 @@ version = "2.1.3" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["main", "docs"] files = [ {file = "numpy-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff"}, {file = "numpy-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5"}, @@ -1714,7 +2153,7 @@ version = "12.2.0" description = "Python Imaging Library (fork)" optional = false python-versions = ">=3.10" -groups = ["main"] +groups = ["main", "docs"] files = [ {file = "pillow-12.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a4e8f36e677d3336f35089648c8955c51c6d386a13cf6ee9c189c5f5bd713a9f"}, {file = "pillow-12.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e589959f10d9824d39b350472b92f0ce3b443c0a3442ebf41c40cb8361c5b97"}, @@ -1990,13 +2429,28 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "pyparsing" +version = "3.3.2" +description = "pyparsing - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.9" +groups = ["docs"] +files = [ + {file = "pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d"}, + {file = "pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] +groups = ["main", "docs"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -2007,14 +2461,14 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2026.1.post1" +version = "2026.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" groups = ["main"] files = [ - {file = "pytz-2026.1.post1-py2.py3-none-any.whl", hash = "sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a"}, - {file = "pytz-2026.1.post1.tar.gz", hash = "sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1"}, + {file = "pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126"}, + {file = "pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a"}, ] [[package]] @@ -2057,7 +2511,7 @@ version = "6.0.3" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" -groups = ["main", "test"] +groups = ["main", "docs", "test"] files = [ {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"}, {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"}, @@ -2134,23 +2588,6 @@ files = [ {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"}, ] -[[package]] -name = "recommonmark" -version = "0.7.1" -description = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects." -optional = false -python-versions = "*" -groups = ["docs"] -files = [ - {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"}, - {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"}, -] - -[package.dependencies] -commonmark = ">=0.8.1" -docutils = ">=0.11" -sphinx = ">=1.3.1" - [[package]] name = "requests" version = "2.33.1" @@ -2327,7 +2764,7 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] +groups = ["main", "docs"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -2351,7 +2788,7 @@ version = "2.8.3" description = "A modern CSS selector implementation for Beautiful Soup." optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["main", "docs"] files = [ {file = "soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95"}, {file = "soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349"}, @@ -2385,18 +2822,18 @@ test = ["matplotlib", "pytest-astropy", "spectral-cube", "tox"] [[package]] name = "sphinx" -version = "7.4.7" +version = "8.1.3" description = "Python documentation generator" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["docs"] files = [ - {file = "sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239"}, - {file = "sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe"}, + {file = "sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2"}, + {file = "sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927"}, ] [package.dependencies] -alabaster = ">=0.7.14,<0.8.0" +alabaster = ">=0.7.14" babel = ">=2.13" colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} docutils = ">=0.20,<0.22" @@ -2406,19 +2843,41 @@ packaging = ">=23.0" Pygments = ">=2.17" requests = ">=2.30.0" snowballstemmer = ">=2.2" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" +sphinxcontrib-applehelp = ">=1.0.7" +sphinxcontrib-devhelp = ">=1.0.6" +sphinxcontrib-htmlhelp = ">=2.0.6" +sphinxcontrib-jsmath = ">=1.0.1" +sphinxcontrib-qthelp = ">=1.0.6" sphinxcontrib-serializinghtml = ">=1.1.9" tomli = {version = ">=2", markers = "python_version < \"3.11\""} [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=6.0)", "importlib-metadata (>=6.0)", "mypy (==1.10.1)", "pytest (>=6.0)", "ruff (==0.5.2)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-docutils (==0.21.0.20240711)", "types-requests (>=2.30.0)"] +lint = ["flake8 (>=6.0)", "mypy (==1.11.1)", "pyright (==1.1.384)", "pytest (>=6.0)", "ruff (==0.6.9)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-Pillow (==10.2.0.20240822)", "types-Pygments (==2.18.0.20240506)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20241005)", "types-requests (==2.32.0.20240914)", "types-urllib3 (==1.26.25.14)"] test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] +[[package]] +name = "sphinx-breeze-theme" +version = "0.13.2" +description = "A clean and modern Sphinx theme with polished API docs." +optional = false +python-versions = ">=3.10" +groups = ["docs"] +files = [ + {file = "sphinx_breeze_theme-0.13.2-py3-none-any.whl", hash = "sha256:ea008094e5fddaf9fad109475e8bc8742cb183b13dc529b233a090e07bc43fb5"}, + {file = "sphinx_breeze_theme-0.13.2.tar.gz", hash = "sha256:6cb2b6c26524970d04080b86f603cf723887f2ac8d02ec0a4d5266b49f816e3f"}, +] + +[package.dependencies] +accessible-pygments = "*" +beautifulsoup4 = "*" +docutils = "*" +emoji = "*" +pygments = "*" +sphinx = ">=8.0" +sphinxext-opengraph = {version = "*", extras = ["social-cards"]} +typing-extensions = "*" + [[package]] name = "sphinx-copybutton" version = "0.5.2" @@ -2464,26 +2923,6 @@ theme-pydata = ["pydata-sphinx-theme (>=0.15.2,<0.16.0)"] theme-rtd = ["sphinx-rtd-theme (>=2.0,<3.0)"] theme-sbt = ["sphinx-book-theme (>=1.1,<2.0)"] -[[package]] -name = "sphinx-rtd-theme" -version = "3.1.0" -description = "Read the Docs theme for Sphinx" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "sphinx_rtd_theme-3.1.0-py2.py3-none-any.whl", hash = "sha256:1785824ae8e6632060490f67cf3a72d404a85d2d9fc26bce3619944de5682b89"}, - {file = "sphinx_rtd_theme-3.1.0.tar.gz", hash = "sha256:b44276f2c276e909239a4f6c955aa667aaafeb78597923b1c60babc76db78e4c"}, -] - -[package.dependencies] -docutils = ">0.18,<0.23" -sphinx = ">=6,<10" -sphinxcontrib-jquery = ">=4,<5" - -[package.extras] -dev = ["bump2version", "transifex-client", "twine", "wheel"] - [[package]] name = "sphinxcontrib-applehelp" version = "2.0.0" @@ -2535,21 +2974,6 @@ lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["html5lib", "pytest"] -[[package]] -name = "sphinxcontrib-jquery" -version = "4.1" -description = "Extension to include jQuery on newer Sphinx releases" -optional = false -python-versions = ">=2.7" -groups = ["docs"] -files = [ - {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, - {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, -] - -[package.dependencies] -Sphinx = ">=1.8" - [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" @@ -2599,6 +3023,26 @@ lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] standalone = ["Sphinx (>=5)"] test = ["pytest"] +[[package]] +name = "sphinxext-opengraph" +version = "0.13.0" +description = "Sphinx Extension to enable OGP support" +optional = false +python-versions = ">=3.9" +groups = ["docs"] +files = [ + {file = "sphinxext_opengraph-0.13.0-py3-none-any.whl", hash = "sha256:936c07828edc9ad9a7b07908b29596dc84ed0b3ceaa77acdf51282d232d4d80e"}, + {file = "sphinxext_opengraph-0.13.0.tar.gz", hash = "sha256:103335d08567ad8468faf1425f575e3b698e9621f9323949a6c8b96d9793e80b"}, +] + +[package.dependencies] +matplotlib = {version = ">=3", optional = true, markers = "extra == \"social-cards\""} +Sphinx = ">=6.0" + +[package.extras] +rtd = ["furo (>=2024)", "sphinx (>=8.1.0,<8.2.0)", "sphinx-design"] +social-cards = ["matplotlib (>=3)"] + [[package]] name = "sqlparse" version = "0.5.5" @@ -2713,7 +3157,7 @@ version = "4.15.0" description = "Backported and Experimental Type Hints for Python 3.9+" optional = false python-versions = ">=3.9" -groups = ["main"] +groups = ["main", "docs"] files = [ {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, @@ -2786,4 +3230,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.10.0,<3.14" -content-hash = "4f45007d0d7bb3917cb97cef6952220c97ac6b93f54a7d12af962e1a4f056d22" +content-hash = "ed90d639b947de6f22c77ffb72ebcc45e82bb6d2a72ca4c85521e31d91d10d6e" diff --git a/pyproject.toml b/pyproject.toml index 4f03d12e2..8408320f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,11 +95,11 @@ psycopg2-binary = "*" # for testing postgres [tool.poetry.group.docs.dependencies] docutils = "!=0.21.post1" -recommonmark = "~0.7" -sphinx = ">=5,<8" +sphinx = ">=8" sphinx-design = ">=0.6,<0.7" -sphinx-rtd-theme = ">=3.1.0,<3.2" +sphinx-breeze-theme = "0.13.2" sphinx-copybutton = "~0.5" +myst-parser = "==4.0.1" [tool.poetry.group.coverage.dependencies] coverage = ">=6,<8" # coveralls needs ~6 even though 7.3.2 is latest @@ -108,7 +108,6 @@ coveralls = ">=3,<5" [tool.poetry.group.lint.dependencies] flake8 = ">=7.3.0,<7.4" - [tool.poetry.requires-plugins] poetry-dynamic-versioning = { version = ">=1.0.0,<2.0.0", extras = ["plugin"] } diff --git a/tom_alerts/alerts.py b/tom_alerts/alerts.py index 9bf6ceb1f..7f45b427e 100644 --- a/tom_alerts/alerts.py +++ b/tom_alerts/alerts.py @@ -16,13 +16,13 @@ DEFAULT_ALERT_CLASSES = [ - 'tom_alerts.brokers.lasair.LasairBroker', - 'tom_alerts.brokers.scout.ScoutBroker', - 'tom_alerts.brokers.alerce.ALeRCEBroker', - # 'tom_alerts.brokers.antares.ANTARESBroker', - 'tom_alerts.brokers.gaia.GaiaBroker', - 'tom_alerts.brokers.fink.FinkBroker', # the stub for the plugin - 'tom_alerts.brokers.hermes.HermesBroker', # the stub for the plugin + 'tom_alerts.dataservices.lasair.LasairBroker', + 'tom_alerts.dataservices.scout.ScoutBroker', + 'tom_alerts.dataservices.alerce.ALeRCEBroker', + # 'tom_alerts.dataservices.antares.ANTARESBroker', + 'tom_alerts.dataservices.gaia.GaiaBroker', + 'tom_alerts.dataservices.fink.FinkBroker', # the stub for the plugin + 'tom_alerts.dataservices.hermes.HermesBroker', # the stub for the plugin ] @@ -178,7 +178,7 @@ class GenericBroker(ABC): https://github.com/TOMToolkit/tom_base/blob/main/tom_alerts/brokers/mars.py """ alert_submission_form = GenericUpstreamSubmissionForm - score_description = "The meaning of this field changes between brokers, please consult this broker's documentation." + score_description = "The meaning of this field changes between dataservices, please consult this broker's documentation." @abstractmethod def fetch_alerts(self, parameters: dict): diff --git a/tom_alerts/brokers/alerce.py b/tom_alerts/brokers/alerce.py index 41a49e923..bf0bf7383 100644 --- a/tom_alerts/brokers/alerce.py +++ b/tom_alerts/brokers/alerce.py @@ -430,7 +430,7 @@ class ALeRCEBroker(GenericBroker): .. code-block:: python TOM_ALERT_CLASSES = [ - 'tom_alerts.brokers.alerce.ALeRCEBroker', + 'tom_alerts.dataservices.alerce.ALeRCEBroker', ... ] diff --git a/tom_alerts/brokers/gaia.py b/tom_alerts/brokers/gaia.py index e1385fabc..3a64894ee 100644 --- a/tom_alerts/brokers/gaia.py +++ b/tom_alerts/brokers/gaia.py @@ -67,7 +67,7 @@ class GaiaBroker(GenericBroker): .. code-block:: python TOM_ALERT_CLASSES = [ - 'tom_alerts.brokers.gaia.GaiaBroker', + 'tom_alerts.dataservices.gaia.GaiaBroker', ... ] diff --git a/tom_alerts/brokers/lasair.py b/tom_alerts/brokers/lasair.py index 98f9881a2..ee8a95d42 100644 --- a/tom_alerts/brokers/lasair.py +++ b/tom_alerts/brokers/lasair.py @@ -87,7 +87,7 @@ class LasairBroker(GenericBroker): .. code-block:: python TOM_ALERT_CLASSES = [ - 'tom_alerts.brokers.lasair.LasairBroker', + 'tom_alerts.dataservices.lasair.LasairBroker', ... ] diff --git a/tom_alerts/brokers/tns.py b/tom_alerts/brokers/tns.py index 3f51b3641..ee4a05578 100644 --- a/tom_alerts/brokers/tns.py +++ b/tom_alerts/brokers/tns.py @@ -90,7 +90,7 @@ class TNSBroker(GenericBroker): .. code-block:: python TOM_ALERT_CLASSES = [ - 'tom_alerts.brokers.tns.TNSBroker', + 'tom_alerts.dataservices.tns.TNSBroker', ... ] diff --git a/tom_alerts/tests/brokers/test_alerce.py b/tom_alerts/tests/brokers/test_alerce.py index 8e3187050..c524f3283 100644 --- a/tom_alerts/tests/brokers/test_alerce.py +++ b/tom_alerts/tests/brokers/test_alerce.py @@ -77,7 +77,7 @@ def setUp(self): 'broker': 'ALeRCE' } - @patch('tom_alerts.brokers.alerce.cache') + @patch('tom_alerts.dataservices.alerce.cache') def test_cone_search_validation(self, mock_cache): """Test cross-field validation for cone search filters.""" @@ -98,7 +98,7 @@ def test_cone_search_validation(self, mock_cache): form = ALeRCEQueryForm(self.base_form_data) self.assertTrue(form.is_valid()) - @patch('tom_alerts.brokers.alerce.cache') + @patch('tom_alerts.dataservices.alerce.cache') def test_time_filters_validation(self, mock_cache): """Test validation for time filters.""" @@ -112,7 +112,7 @@ def test_time_filters_validation(self, mock_cache): form = ALeRCEQueryForm(parameters) self.assertTrue(form.is_valid()) - @patch('tom_alerts.brokers.alerce.cache.get') + @patch('tom_alerts.dataservices.alerce.cache.get') def test_classifier_filters_validation(self, mock_cache_get): mock_cache_get.return_value = alerce_classifiers_response @@ -139,8 +139,8 @@ def test_classifier_filters_validation(self, mock_cache_get): self.assertIn('Only one of either light curve or stamp classification may be used as a filter.', form.errors['__all__']) - @patch('tom_alerts.brokers.alerce.cache.get') - @patch('tom_alerts.brokers.alerce.requests.get') + @patch('tom_alerts.dataservices.alerce.cache.get') + @patch('tom_alerts.dataservices.alerce.requests.get') def test_get_classifiers(self, mock_requests_get, mock_cache_get): mock_response = Response() mock_response._content = str.encode(json.dumps(alerce_classifiers_response)) @@ -161,7 +161,7 @@ def test_get_classifiers(self, mock_requests_get, mock_cache_get): classifiers = ALeRCEQueryForm._get_classifiers() mock_requests_get.assert_called_once() - @patch('tom_alerts.brokers.alerce.cache.get') + @patch('tom_alerts.dataservices.alerce.cache.get') def test_get_light_curve_classifier_choices(self, mock_cache_get): mock_cache_get.return_value = alerce_classifiers_response lc_classifiers = ALeRCEQueryForm._get_light_curve_classifier_choices() @@ -174,7 +174,7 @@ def test_get_light_curve_classifier_choices(self, mock_cache_get): for classifier in expected_classifiers: self.assertIn(classifier, lc_classifiers) - @patch('tom_alerts.brokers.alerce.cache.get') + @patch('tom_alerts.dataservices.alerce.cache.get') def test_get_stamp_classifier_choices(self, mock_cache_get): mock_cache_get.return_value = alerce_classifiers_response stamp_classifiers = ALeRCEQueryForm._get_stamp_classifier_choices() @@ -269,9 +269,9 @@ def test_clean_classifier_parameters(self): cleaned_classifier_parameters = self.broker._clean_classifier_parameters(parameters) self.assertIn(expected, cleaned_classifier_parameters) - @patch('tom_alerts.brokers.alerce.ALeRCEBroker._clean_classifier_parameters') - @patch('tom_alerts.brokers.alerce.ALeRCEBroker._clean_date_parameters') - @patch('tom_alerts.brokers.alerce.ALeRCEBroker._clean_coordinate_parameters') + @patch('tom_alerts.dataservices.alerce.ALeRCEBroker._clean_classifier_parameters') + @patch('tom_alerts.dataservices.alerce.ALeRCEBroker._clean_date_parameters') + @patch('tom_alerts.dataservices.alerce.ALeRCEBroker._clean_coordinate_parameters') def test_clean_parameters(self, mock_coordinate, mock_date, mock_classifier): mock_coordinate.return_value = [('ra', 10), ('dec', 10), ('radius', 10)] mock_date.return_value = [('firstmjd', 57000), ('firstmjd', 58000), ('lastmjd', 58000), ('lastmjd', 59000)] @@ -297,8 +297,8 @@ def test_clean_parameters(self, mock_coordinate, mock_date, mock_classifier): with self.subTest(): self.assertIn(('page', 1), payload) - @patch('tom_alerts.brokers.alerce.requests.get') - @patch('tom_alerts.brokers.alerce.ALeRCEBroker._clean_parameters') + @patch('tom_alerts.dataservices.alerce.requests.get') + @patch('tom_alerts.dataservices.alerce.ALeRCEBroker._clean_parameters') def test_fetch_alerts(self, mock_clean_parameters, mock_requests_get): """Test fetch_alerts broker method.""" first_mock_response_content = create_alerce_query_response(20, page=1) @@ -331,7 +331,7 @@ def test_fetch_alerts(self, mock_clean_parameters, mock_requests_get): alerts.append(alert) self.assertEqual(20, len(alerts)) - @patch('tom_alerts.brokers.alerce.requests.get') + @patch('tom_alerts.dataservices.alerce.requests.get') def test_fetch_alert(self, mock_requests_post): """Test fetch_alert broker method.""" alert = create_alerce_alert(1) @@ -354,7 +354,7 @@ def test_to_target(self): self.assertEqual(mock_alert['meanra'], t.ra) self.assertEqual(mock_alert['meandec'], t.dec) - @patch('tom_alerts.brokers.alerce.ALeRCEBroker.fetch_lightcurve') + @patch('tom_alerts.dataservices.alerce.ALeRCEBroker.fetch_lightcurve') def test_process_reduced_datum(self, mock_fetch_lightcurve): test_data = { "detections": [{ @@ -438,7 +438,7 @@ def setUp(self): 'broker': 'ALeRCE', } - @patch('tom_alerts.brokers.alerce.cache.get') + @patch('tom_alerts.dataservices.alerce.cache.get') def test_get_classifiers(self, mock_cache_get): mock_cache_get.return_value = None # Ensure cache is not used diff --git a/tom_alerts/tests/brokers/test_gaia.py b/tom_alerts/tests/brokers/test_gaia.py index 803032306..2ccbfa54e 100644 --- a/tom_alerts/tests/brokers/test_gaia.py +++ b/tom_alerts/tests/brokers/test_gaia.py @@ -12,7 +12,7 @@ from tom_dataproducts.models import ReducedDatum -@override_settings(TOM_ALERT_CLASSES=['tom_alerts.brokers.gaia.GaiaBroker']) +@override_settings(TOM_ALERT_CLASSES=['tom_alerts.dataservices.gaia.GaiaBroker']) class TestGaiaQueryForm(TestCase): def setUp(self): self.base_form_params = {'query_name': 'Test Query', 'broker': 'Gaia'} @@ -59,7 +59,7 @@ def test_cone_invalid_format(self): self.assertIn('Cone search parameters must be in the format \'RA,Dec,Radius\'.', form.errors.get('cone')) -@override_settings(TOM_ALERT_CLASSES=['tom_alerts.brokers.gaia.GaiaBroker']) +@override_settings(TOM_ALERT_CLASSES=['tom_alerts.dataservices.gaia.GaiaBroker']) class TestGaiaBroker(TestCase): def setUp(self): self.test_html = """ @@ -111,7 +111,7 @@ def setUp(self): value=12345.6789 ) - @mock.patch('tom_alerts.brokers.gaia.requests.get') + @mock.patch('tom_alerts.dataservices.gaia.requests.get') def test_fetch_alerts(self, mock_requests_get): mock_response = Response() mock_response._content = self.test_html @@ -130,7 +130,7 @@ def test_to_generic_alert(self): alert = GaiaBroker().to_generic_alert(self.alert_list[0]) self.assertEqual(alert.name, self.alert_list[0]['name']) - @mock.patch('tom_alerts.brokers.gaia.requests.get') + @mock.patch('tom_alerts.dataservices.gaia.requests.get') def test_process_reduced_data_with_alert(self, mock_requests_get): mock_photometry_response = Response() @@ -145,8 +145,8 @@ def test_process_reduced_data_with_alert(self, mock_requests_get): self.assertGreater(reduced_data.count(), 1) self.assertEqual(reduced_data.count(), 3) # one from setUp and two from this test - @mock.patch('tom_alerts.brokers.gaia.requests.get') - @mock.patch('tom_alerts.brokers.gaia.GaiaBroker.fetch_alerts') + @mock.patch('tom_alerts.dataservices.gaia.requests.get') + @mock.patch('tom_alerts.dataservices.gaia.GaiaBroker.fetch_alerts') def test_process_reduced_data_without_alert(self, mock_fetch_alerts, mock_requests_get): mock_fetch_alerts.return_value = iter([self.alert_list[1]]) @@ -171,7 +171,7 @@ def test_rewrite_process_reduced_data_with_alert(self): There are TWO ReducedDatums in the _content mocked below. """ - with mock.patch('tom_alerts.brokers.gaia.requests.get') as mock_requests_get: + with mock.patch('tom_alerts.dataservices.gaia.requests.get') as mock_requests_get: mock_photometry_response = Response() mock_photometry_response._content = str.encode('''Gaia20bph\n#Date,JD,averagemag.\n 2014-08-01 00:05:24,2456870.504,19.48\n2014-08-01 06:05:38,2456870.754,19.48\n\n''') diff --git a/tom_alerts/tests/brokers/test_lasair.py b/tom_alerts/tests/brokers/test_lasair.py index d0c82c2f1..5d5d02237 100644 --- a/tom_alerts/tests/brokers/test_lasair.py +++ b/tom_alerts/tests/brokers/test_lasair.py @@ -54,7 +54,7 @@ def test_clean(self): self.assertTrue(form.is_valid()) -@override_settings(TOM_ALERT_CLASSES=['tom_alerts.brokers.lasair.LasairBroker']) +@override_settings(TOM_ALERT_CLASSES=['tom_alerts.dataservices.lasair.LasairBroker']) class TestLasairBrokerClass(TestCase): """ Test the functionality of the LasairBroker, we modify the django settings to make sure @@ -67,7 +67,7 @@ def setUp(self): def test_get_broker_class(self): self.assertEqual(LasairBroker, get_service_class('Lasair')) - @mock.patch('tom_alerts.brokers.lasair.requests.get') + @mock.patch('tom_alerts.dataservices.lasair.requests.get') def test_fetch_alerts(self, mock_requests_get): pass diff --git a/tom_alerts/tests/tests.py b/tom_alerts/tests/tests.py index fbf9984a6..08bbdba89 100644 --- a/tom_alerts/tests/tests.py +++ b/tom_alerts/tests/tests.py @@ -24,7 +24,7 @@ class TestBrokerForm(GenericQueryForm): - """ All brokers must have a form which will be used to construct and save queries + """ All dataservices must have a form which will be used to construct and save queries to the broker. They should subclass `GenericQueryForm` which includes some required fields and contains logic for serializing and persisting the query parameters to the database. This test form will only have one field. @@ -42,7 +42,7 @@ class TestUpstreamSubmissionForm(GenericUpstreamSubmissionForm): class TestBroker(GenericBroker): - """ The broker class encapsulates the logic for querying remote brokers and transforming + """ The broker class encapsulates the logic for querying remote dataservices and transforming the returned data into TOM Toolkit Targets so they can be used elsewhere in the system. The following methods and attributes are all required, but a broker can be as complex as needed. """ @@ -51,13 +51,13 @@ class TestBroker(GenericBroker): alert_submission_form = TestUpstreamSubmissionForm def fetch_alerts(self, parameters): - """ All brokers must implement this method. It must return a list of alerts and may include broker feedback. + """ All dataservices must implement this method. It must return a list of alerts and may include broker feedback. """ # Here we simply return a list of `GenericAlert`s that match the name passed in via `parameters`. return iter([alert for alert in test_alerts if alert['name'] == parameters['name']]), "test message" def no_message_fetch_alerts(self, parameters): - """ Older brokers might implement this version of the fetch_alerts method. It returns a list of alerts. + """ Older dataservices might implement this version of the fetch_alerts method. It returns a list of alerts. """ # Here we simply return a list of `GenericAlert`s that match the name passed in via `parameters`. return iter([alert for alert in test_alerts if alert['name'] == parameters['name']]) diff --git a/tom_alerts/views.py b/tom_alerts/views.py index ca8f75218..b81a2c57f 100644 --- a/tom_alerts/views.py +++ b/tom_alerts/views.py @@ -164,7 +164,7 @@ class BrokerQueryListView(LoginRequiredMixin, FilterView): def get_context_data(self, *args, **kwargs): """ - Adds the brokers available to the TOM to the context dictionary. + Adds the dataservices available to the TOM to the context dictionary. :returns: context :rtype: dict @@ -227,7 +227,7 @@ def get_context_data(self, *args, **kwargs): broker_class = get_service_class(query.broker)() # Do query and get query results (fetch_alerts) - # TODO: Should the deepcopy be in the brokers? + # TODO: Should the deepcopy be in the dataservices? try: alert_query_results = broker_class.fetch_alerts(deepcopy(query.parameters))