Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F5972573
schema.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
schema.py
View Options
# -*- coding: utf-8 -*-
"""
eventlogging.schema
~~~~~~~~~~~~~~~~~~~
This module implements schema retrieval and validation. Schemas are
referenced via SCIDs, which are tuples of (Schema name, Revision ID).
Schemas are retrieved via HTTP and then cached in-memory.
"""
import
json
import
re
from
urllib.request
import
urlopen
import
jsonschema
__all__
=
(
'get_schema'
)
# Regular expression which matches valid schema names.
SCHEMA_RE_PATTERN
=
r'[a-zA-Z0-9_-]{1,63}'
SCHEMA_RE
=
re
.
compile
(
r'^{0}$'
.
format
(
SCHEMA_RE_PATTERN
))
# URL of index.php on the schema wiki (same as
# '$wgEventLoggingSchemaApiUri').
SCHEMA_WIKI_API
=
'https://meta.wikimedia.org/w/api.php'
# Template for schema article URLs. Interpolates SCIDs.
SCHEMA_URL_FORMAT
=
(
SCHEMA_WIKI_API
+
'?format=json&action=jsonschema&title=
%s
&revid=
%s
&formatversion=2'
)
# Schemas retrieved via HTTP are cached in this dictionary.
schema_cache
=
{}
# SCID of the metadata object which wraps each event.
CAPSULE_SCID
=
(
'EventCapsule'
,
10981547
)
def
http_get
(
url
):
"""Simple wrapper around the standard library's `urlopen` function which
works around a circular ref. See <https://bugs.python.org/issue1208304>.
"""
req
=
None
try
:
req
=
urlopen
(
url
)
return
req
.
read
()
.
decode
(
'utf-8'
)
finally
:
if
req
is
not
None
:
if
hasattr
(
req
,
'fp'
)
and
hasattr
(
req
.
fp
,
'_sock'
):
req
.
fp
.
_sock
.
recv
=
None
req
.
close
()
def
get_schema
(
scid
,
encapsulate
=
False
):
"""Get schema from memory or HTTP."""
schema
=
schema_cache
.
get
(
scid
)
if
schema
is
None
:
schema
=
http_get_schema
(
scid
)
schema_cache
[
scid
]
=
schema
# We depart from the JSON Schema specifications by disallowing
# additional properties by default.
# See `<https://bugzilla.wikimedia.org/show_bug.cgi?id=44454>`_.
schema
.
setdefault
(
'additionalProperties'
,
False
)
if
encapsulate
:
capsule
=
get_schema
(
CAPSULE_SCID
)
capsule
[
'properties'
][
'event'
]
=
schema
return
capsule
return
schema
def
http_get_schema
(
scid
):
"""Retrieve schema via HTTP."""
validate_scid
(
scid
)
url
=
SCHEMA_URL_FORMAT
%
scid
try
:
schema
=
json
.
loads
(
http_get
(
url
))
except
(
ValueError
,
EnvironmentError
)
as
ex
:
raise
jsonschema
.
SchemaError
(
'Schema fetch failure:
%s
'
%
ex
)
jsonschema
.
Draft3Validator
.
check_schema
(
schema
)
return
schema
def
validate_scid
(
scid
):
"""Validates an SCID.
:raises :exc:`jsonschema.ValidationError`: If SCID is invalid.
"""
schema
,
revision
=
scid
if
not
isinstance
(
revision
,
int
)
or
revision
<
1
:
raise
jsonschema
.
ValidationError
(
'Invalid revision ID:
%s
'
%
revision
)
if
not
isinstance
(
schema
,
str
)
or
not
SCHEMA_RE
.
match
(
schema
):
raise
jsonschema
.
ValidationError
(
'Invalid schema name:
%s
'
%
schema
)
File Metadata
Details
Attached
Mime Type
text/x-script.python
Expires
Sat, Oct 3, 16:00 (1 d, 15 h ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
a7/8b/547828aebdb49dce9d249d5e735b
Default Alt Text
schema.py (2 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment