15.2.89. camcops_server.camcops_server_core¶
camcops_server/camcops_server_core.py
Copyright (C) 2012, University of Cambridge, Department of Psychiatry. Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
This file is part of CamCOPS.
CamCOPS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
CamCOPS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
Main functions used by camcops_server.py
We split these off, because the imports can be very slow, and we want a rapid command-line response for simple commands.
Importing this module does the following:
ensure that all models are loaded;
provide log message around some of the slow imports.
- camcops_server.camcops_server_core.check_index(cfg: camcops_server.cc_modules.cc_config.CamcopsConfig, show_all_bad: bool = False) bool [source]¶
Checks the server task index for validity.
- Parameters
show_all_bad – show all bad entries? (If false, return upon the first)
- Returns
are the indexes all good?
- camcops_server.camcops_server_core.cmd_export(recipient_names: Optional[List[str]] = None, all_recipients: bool = False, via_index: bool = True, schedule_via_backend: bool = False) None [source]¶
Send all outbound incremental export messages (e.g. HL7).
- Parameters
recipient_names – List of export recipient names (as per the config file).
all_recipients – Use all recipients?
via_index – Use the task index (faster)?
schedule_via_backend – Schedule the export via the backend, rather than performing it now.
- camcops_server.camcops_server_core.cmd_show_export_queue(recipient_names: Optional[List[str]] = None, all_recipients: bool = False, via_index: bool = True, pretty: bool = False, debug_show_fhir: bool = False, debug_fhir_include_docs: bool = False) None [source]¶
Shows tasks that would be exported.
- Parameters
recipient_names – List of export recipient names (as per the config file).
all_recipients – Use all recipients?
via_index – Use the task index (faster)?
pretty – Use
str(task)
notrepr(task)
? (Prettier, but slower because it has to query the patient.)debug_show_fhir – Show FHIR output for each task, as JSON?
debug_fhir_include_docs – (If debug_show_fhir.) Include document content? Large!
- camcops_server.camcops_server_core.enable_user_cli(username: Optional[str] = None) bool [source]¶
Re-enable a locked user account from the command line.
- camcops_server.camcops_server_core.ensure_database_is_ok() None [source]¶
Opens a link to the database and checks it’s of the correct version (or otherwise raises an assertion error).
- camcops_server.camcops_server_core.ensure_ok_for_webserver() None [source]¶
Prerequisites for firing up the web server.
- camcops_server.camcops_server_core.get_new_password_from_cli(username: str) str [source]¶
Asks the user (via stdout/stdin) for a new password for the specified username. Returns the password.
- camcops_server.camcops_server_core.get_username_from_cli(req: camcops_server.cc_modules.cc_request.CamcopsRequest, prompt: str, starting_username: str = '', must_exist: bool = False, must_not_exist: bool = False) str [source]¶
Asks the user (via stdout/stdin) for a username.
- Parameters
req – CamcopsRequest object
prompt – textual prompt
starting_username – try this username and ask only if it fails tests
must_exist – the username must exist
must_not_exist – the username must not exist
- Returns
the username
- camcops_server.camcops_server_core.join_url_fragments(*fragments: str) str [source]¶
Combines fragments to make a URL.
(
urllib.parse.urljoin
doesn’t do what we want.)
- camcops_server.camcops_server_core.launch_celery_beat(verbose: bool = False, cleanup_timeout_s: float = 10.0) None [source]¶
Launch the Celery Beat scheduler.
(This can be combined with
celery worker
, but that’s not recommended; https://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html#starting-the-scheduler).
- camcops_server.camcops_server_core.launch_celery_flower(address: str = '127.0.0.1', port: int = 5555, cleanup_timeout_s: float = 10.0) None [source]¶
Launch the Celery Flower monitor.
- camcops_server.camcops_server_core.launch_celery_workers(verbose: bool = False, cleanup_timeout_s: float = 10.0) None [source]¶
Launch Celery workers.
See also advice in
- camcops_server.camcops_server_core.make_data_dictionary(filename: str, recipient_name: str, cris: bool = False) None [source]¶
Writes a data dictionary for the CRATE anonymisation tool. See
camcops_server.cc_export.write_crate_data_dictionary()
.- Parameters
filename – destination filename
recipient_name – export recipient name
cris – make DD for CRIS, not CRATE
- camcops_server.camcops_server_core.make_superuser(username: Optional[str] = None, password: Optional[str] = None) bool [source]¶
Make a superuser from the command line.
- camcops_server.camcops_server_core.make_wsgi_app(debug_toolbar: bool = False, reverse_proxied_config: cardinal_pythonlib.wsgi.reverse_proxied_mw.ReverseProxiedConfig = None, debug_reverse_proxy: bool = False, show_requests: bool = True, show_request_immediately: bool = True, show_response: bool = True, show_timing: bool = True, static_cache_duration_s: int = 0) Router [source]¶
Makes and returns a WSGI application, attaching all our special methods.
- Parameters
debug_toolbar – Add the Pyramid debug toolbar?
reverse_proxied_config – An optional
cardinal_pythonlib.wsgi.reverse_proxied_mw.ReverseProxiedConfig
object giving details about a reverse proxy configuration (or details that there isn’t one)debug_reverse_proxy – Show debugging information about the reverse proxy middleware, if such middleware is required?
show_requests – Write incoming requests to the Python log?
show_request_immediately – [Applicable if
show_requests
] Show the request immediately, so it’s written to the log before the WSGI app does its processing, and is guaranteed to be visible even if the WSGI app hangs? The only reason to useFalse
is probably if you intend to show response and/or timing information and you want to minimize the number of lines written to the log; in this case, only a single line is written to the log (after the wrapped WSGI app has finished processing).show_response – [Applicable if
show_requests
] Show the HTTP response code?show_timing – [Applicable if
show_requests
] Show the time that the wrapped WSGI app took?static_cache_duration_s – Lifetime (in seconds) for the HTTP cache-control setting for static content.
- Returns
the WSGI app
QUESTION: how do we access the WSGI environment (passed to the WSGI app) from within a Pyramid request?
ANSWER:
Configurator.make_wsgi_app() calls Router.__init__() and returns: app = Router(...) The WSGI framework uses: response = app(environ, start_response) which therefore calls: Router.__call__(environ, start_response) which does: response = self.execution_policy(environ, self) return response(environ, start_response) So something LIKE this will be called: Router.default_execution_policy(environ, router) with router.request_context(environ) as request: # ... So the environ is handled by Router.request_context(environ) which will call BaseRequest.__init__() which does: d = self.__dict__ d['environ'] = environ so we should be able to use request.environ # type: Dict[str, str]
- camcops_server.camcops_server_core.precache() None [source]¶
Populates the major caches. (These are process-wide caches, e.g. using dogpile’s
@cache_region_static.cache_on_arguments
, not config-specific caches.)
- camcops_server.camcops_server_core.print_database_title() None [source]¶
Prints the database title (for the current config) to stdout.
- camcops_server.camcops_server_core.print_tasklist() None [source]¶
Prints the list of tasks to stdout.
- camcops_server.camcops_server_core.reindex(cfg: camcops_server.cc_modules.cc_config.CamcopsConfig) None [source]¶
Drops and regenerates the server task index.
- Parameters
- camcops_server.camcops_server_core.reset_password(username: Optional[str] = None) bool [source]¶
Reset a password from the command line.
- camcops_server.camcops_server_core.serve_cherrypy(application: Router, host: str, port: int, unix_domain_socket_filename: str, threads_start: int, threads_max: int, server_name: str, log_screen: bool, ssl_certificate: Optional[str], ssl_private_key: Optional[str], root_path: str) None [source]¶
Start CherryPy server.
Multithreading.
Any platform.
- camcops_server.camcops_server_core.serve_gunicorn(application: Router, host: str, port: int, unix_domain_socket_filename: str, num_workers: int, ssl_certificate: Optional[str], ssl_private_key: Optional[str], reload: bool = False, timeout_s: int = 30, debug_show_gunicorn_options: bool = False) None [source]¶
Start Gunicorn server
Multiprocessing; this is a Good Thing particularly in Python; see e.g.
UNIX only.
The Pyramid debug toolbar detects a multiprocessing web server and says “shan’t, because I use global state”.
- camcops_server.camcops_server_core.show_database_schema(schemastem: str, make_image: bool = False, java: Optional[str] = None, plantuml: Optional[str] = None, height_width_limit: int = 20000, java_memory_limit_mb: int = 2048) None [source]¶
Prints the database schema to a PNG picture.
- Parameters
schemastem – filename stem
make_image – Make a PNG image? (May be impractically large!)
java – (for
make_image
) Java executableplantuml – (for
make_image
) PlantUML Java.jar
fileheight_width_limit – (for
make_image
) maximum height and width for PNG; see https://plantuml.com/faqjava_memory_limit_mb – (for
make_image
) Java virtual machine memory limit, in Mb