Skip to content

Release candidate - #67

Draft
oleksandrlazarenko-pi wants to merge 30 commits into
mainfrom
rc
Draft

oleksandrlazarenko-pi wants to merge 30 commits into
mainfrom
rc

Conversation

@oleksandrlazarenko-pi

Copy link
Copy Markdown
Contributor

Releases what has collected on rc since #39:

  • #40 Allow only http and https in the callback URL, and test the zone and port rules
  • #41 Test every package against the packages it depends on in this checkout
  • #44 Use a name in the object name test that a session id cannot contain
  • #43 Run every example on the free data files, and show what needs the Enterprise data file
  • #45 Build the released packages when a nightly publish has nothing to release
  • #50 Share only the evidence usage sharing accepts unless asked for all
  • #58 Fail the cloud tests when no resource key is set, and run the Cloud 51Did workflow
  • #65 Make the example profile comments and the Lite file name match the code
  • #62 Use the Balanced performance profile by default for IP Intelligence
  • #64 Accept the specification's translation option names, and the behavior as text

Closes #42. The scheduled nightly runs from main, so #45 stops it failing only once this is merged.

Release note

Notes

No commit asks for a major or minor version change, so the publish moves only patch numbers.

The last release into main was #39, merged at 23:05 UTC on 4 November 2026.

jwrosewell and others added 26 commits November 3, 2026 21:02
* Point the documentation build at the example folders and package

List the cloud request engine examples and the device detection examples
source folder in EXAMPLE_PATH, so Doxygen finds the files the examples
name. Include each client hints example's template from its own folder,
and read the location package from src/fiftyone_location.

* Keep the cloud web example doc comment unbroken and name its view by folder

* Keep the onpremise web example doc comment unbroken and name its view by folder
…25)

* Point links to the archived repositories at where the code now lives

The examples, readmes and example web pages linked to the archived
Python repositories, and the IP Intelligence readmes linked to the
archived IP Intelligence C repository. Each link now points at the same
file or folder in 51degrees-python, or at the IP Intelligence readme in
51degrees-cxx, so readers land on code that is still maintained.

Links to a file follow the file to its folder in this repository, for
example the Device Detection examples now sit under
device-detection/fiftyone_devicedetection_examples/src. Links that used
the old version/4.5 branch now use main.

The match metrics example closed its Markdown link with a square bracket
instead of a parenthesis. The link now closes with a parenthesis. The
cloud examples readme changes into the cloned folder after cloning, so
its cd line now follows the new clone address.

The history table in the root README still names the earlier
repositories, because their tags and releases stay there. The links to
the data repositories are unchanged, because those repositories are
still current.

* Describe the IP Intelligence performance test gap without old repository names
* Add a temporary workflow that generates the SWIG wrappers for 51degrees-cxx 4.5.102

* Name the SWIG modules in the temporary workflow instead of reading them

* Generate both SWIG wrappers again for 51degrees-cxx 4.5.102

Between 4.5.100 and 4.5.102, 51degrees-cxx removed the two
EngineHash process overloads and the three EngineIpi process
overloads that take required property indexes. The committed
wrappers still called them, so neither on-premise package compiled
against 4.5.102, which the nightly submodule update brings in #26.

This moves the cxx submodule from 4110d681, the 4.5.100 release, to
1bec7b57, the 4.5.102 release, and generates hash_python_wrap.cxx,
DeviceDetectionHashEngineModule.py, ipi_python_wrap.cxx and
IpIntelligenceEngineModule.py again with SWIG 4.4.1 built from its
v4.4.1 tag. Run against 4110d681, the same command gives files byte
for byte the same as the ones committed before, so every difference
here comes from cxx. Both engines call only process(evidence), which
cxx keeps.

* Remove the temporary SWIG wrapper workflow
Co-authored-by: Automation51D <51DCI@51Degrees.com>
…1Did workflow (#58)

* Fail the cloud tests when no resource key is set, and run the Cloud 51Did workflow

Tests that exist to call the live cloud service skipped when no resource
key reached them, and the 51Did live tests also skipped when the answer
lacked what they checked, so a run with no key or with a key lacking a
product reported success without the cloud being called.

- Each test folder that calls the live service has the same live_cloud.py,
  which reads _51DEGREES_RESOURCE_KEY, then _51DEGREES_RESOURCE_KEY_BESPOKE,
  then resource_key, and gives the failure messages. Every skip for a
  missing key in the 51Did, Device Detection cloud, Device Detection
  example, IP Intelligence example and pipeline example tests is now a
  failure naming the variables, the product the key must carry and how to
  see what a key carries.
- Where the 51Did answer lacks an identifier, the failure gives the cloud's
  null reason and the product. A host without the creator context fails.
  Without a licence key the redeem tests check the sealed result redeems as
  unreadable.
- test_did_tier_live.py checks what a Basic key gets, being a 51Did for
  non-marketing and a refusal naming CloudV5FODiD for standard and
  personalized.
- The live tests are marked, the unit steps deselect them through
  PYTEST_ADDOPTS, and the pipeline integration step now runs the 51Did
  live tests. The integration scripts fail when no TestResourceKey is
  passed, and the Device Detection one keeps the cloud package in the run
  when 51Degrees.csv is missing.
- cloud-51did.yml moves to the root .github/workflows, where GitHub reads
  it, with its paths corrected. It fails when no key reaches it, and runs
  the Basic key only through the tier test.

The licence-key tests in the pipeline examples and test_licensekey_live.py
still skip, because CI has no cloud licence key yet (#13).

* Wrap the tox.ini comment about the cloud test keys
…de (#65)

- The IP Intelligence data file update example now names the LowMemory
  profile for the pipeline that downloads and reloads the Enterprise data
  file, rather than taking the engine's default.
- The Device Detection getting started example's comment said it uses the
  low memory profile, but the code sets MaxPerformance. The comment now
  says MaxPerformance, and why it suits the free Lite data file.
- The IP Intelligence performance example's header said worker processes
  share a memory mapped data file under LowMemory, as if that were the
  default. It now says the default MaxPerformance loads the whole file
  into each worker, and that -p LowMemory lets the workers share the
  operating system's file cache.
- The IP Intelligence package readme named the Lite data file
  51Degrees-LiteIpiV41.ipi, which is CI's name for it. The data
  repository's scripts save it as 51Degrees-LiteV41.ipi.
)

The IP Intelligence on-premise specification gives Balanced as the
default performance profile, and the C library's default IP Intelligence
configuration is the Balanced one, but the Python engine defaulted to
LowMemory. The engine now defaults to "Balanced", which its profile
switch already maps to the native Balanced configuration, and the
docstrings in the engine and both builders say so.

Balanced loads some collections into memory and caches others, where
LowMemory reads everything from the data file, so a caller relying on the
default uses more memory. Naming "LowMemory" keeps the previous behaviour.

A new test, on the free ASN data file, compares the collection settings
of the configuration an engine built at its defaults gives the native
code with those of each profile, because the engine keeps no name for the
profile in use.
… as text (#64)

* Accept the missing translation behavior as text, and refuse an unknown one

TranslationEngineBase and Translator stored the behavior they were given
without checking it, and compared it with the MissingTranslationBehavior
members. A configuration file can only give text, so a configuration
naming "EmptyString" or "flow_error" matched no member and a missing
translation kept its original value, with nothing to say the setting had
been ignored.

MissingTranslationBehavior.from_value now returns a member as it is, and
turns text naming a member into that member. It takes the
specification's names (Original, EmptyString, FlowError) and the members'
own names and values, ignoring case and underscores, and raises
ValueError for anything else. The engine and the translator use it, so
an unknown value stops the engine being built. The parameter is still
named behavior.

* Accept the specification's name for the missing translation behavior

The specification names the Translation Engine's options
SourceElementDataKey and MissingTranslationBehavior. Python already took
source_element_data_key, but named the second option behavior.

TranslationEngineBase and Translator now take missing_translation_behavior.
behavior still works as a keyword-only deprecated alias that raises a
DeprecationWarning, and when both are given missing_translation_behavior
wins. Neither given means Original, as before. A value given by position
is taken as missing_translation_behavior, as it was taken as behavior.

The IP Intelligence translation engines now pass every option by its name,
so they need a fiftyone_pipeline_translation that takes the new name. Their
package requires fiftyone_pipeline_translation 4.5.43 or later, the
version the release plan gives this commit.

* Leave the IP Intelligence translation engines as they were on rc

The IP Intelligence translation engines pass the missing translation
behavior by position. A value passed by position is taken as
missing_translation_behavior by the new translation package and as
behavior by the old one, so the engines work with either release and
raise no deprecation warning without any change. Passing it by name
needed a minimum version of fiftyone_pipeline_translation that cannot be
known until the release that carries the new name, so the engines and
their package's requirements are back to their rc content.

* Take None as not given for the missing translation behavior

rc treated None as Original, because the translator took any value that
was not EMPTY_STRING or FLOW_ERROR as Original. Refusing it would stop a
configuration holding null, or code passing an unset option on as None,
from building after a patch release. The repository's other engines use
None to mean not set, so the translation engine and Translator now do the
same. Both parameters default to None, None under either name gives
Original without a warning, and anything else that names no member is
still refused.
@jwrosewell

Copy link
Copy Markdown
Contributor

Converted back to a draft so the shared Pull Requests workflow can't merge it before #57 is in rc. rc already has #62, which starts IP Intelligence on the Balanced profile, but Device Detection only moves to the specification's defaults (Balanced, with Update Matched User Agent on) in #57, whose full build is running. Releasing rc before #57 would ship the two engines on different defaults. Once #57 is merged into rc, this can be marked ready again.

…or (#68)

Name the competitor brands people search for in the remaining package text. Text only, no code change.
* Check the callback URL as the specification's six rules say

Refuse an IPv6 zone identifier, an '@', '?' or '#' anywhere in the host value, and a name ending in a number unless it is an IPv4 address in dotted decimal form. The logged URL shows *** in place of everything in the host before its last '@'.

* Test that a port which is present is not empty

* Refuse a port that is present but empty

A host such as https://example.com otherwise reads as the host https with an empty port. RFC 3986 section 3.2.3 allows an empty port, but section 6.2.3 treats it as equal to none, so the callback URL does not carry one.
…ets (#56)

* Refuse a 51Did text with white space inside it, or both base64 alphabets

The 51Did specification says a reader ignores white space before and
after the text, being any character with the Unicode White_Space
property, refuses any other character outside the alphabet, white space
inside the text included, and refuses a text holding a character from
each alphabet, checking that before it maps "-" and "_" onto "+" and "/".

FodId.to_standard_base64 now removes exactly the White_Space characters
around the text, and answers None for a text holding any other character
outside the two alphabets and the padding, or holding a character from
each alphabet. The base64 readers report InvalidBase64 for such a text.
White space alone still reports MissingInput.

Before this change the reader read a mixed text as if it were clean, and
read a text with U+001C to U+001F around it, because str.strip() removes
those characters although they are not White_Space. White space inside
the text was already refused by the OWID decoder.

The client's length check and to_base64_url trim the same characters.

* Say the alphabet check is made separately in the fod_id comment
…te Matched User Agent (#57)

* Leave Update Matched User Agent on by default, as the native code sets it

The Device Detection on-premise specification says the option is on by
default, so the UserAgents property holds the matched characters of the
evidence. The C library sets it on, but the Python engine took
update_matched_useragent=False and always passed it on, so UserAgents was
a list of empty strings unless a caller turned the option on.

The engine now takes None and only sets the option when a value is given,
so the native default applies, as the .NET builder does. The docstrings in
the engine and both builders say the option is on by default, and the
match metrics example's comment no longer says it has to be set.

A new test builds a pipeline on the free Lite data file with the option
left unset, set on and set off, and skips when that file is not there.

* Use the Balanced performance profile by default, as the native code does

The Device Detection on-premise specification gives Balanced as the
default performance profile, and the C library's default configuration is
the Balanced one, but the Python engine defaulted to LowMemory. The engine
now defaults to "Balanced", which its profile switch already maps to the
native Balanced configuration, and the docstrings in the engine and both
builders say so.

Balanced loads some collections into memory and caches others, where
LowMemory reads everything from the data file, so a caller relying on the
default uses more memory. Naming "LowMemory" keeps the previous behaviour.

A new test compares the collection settings of the configuration an
engine built at its defaults gives the native code with those of each
profile, because the engine keeps no name for the profile in use.

* Say which profiles the default profile test cannot tell apart

MaxPerformance and LowMemory have the same collection settings, as do Balanced and BalancedTemp, so the test's comparison of collection settings cannot separate either pair. The test's docstring now says so.

* Say what the matched User-Agent length limit does, as the C header does

The max_matched_useragent_length docstrings in the engine and both
builders said the option is ignored when update_matched_useragent is
false, and named it max_matched_useragents_length. The C library's header
(src/dd/config-dd.h) says the limit applies to a single header, a pseudo
header and the matched User-Agent, that a longer value is ignored and
detection moves on, and that the limit applies whether or not the matched
User-Agent is recorded. The docstrings now say the same, give the native
default of 500, and spell the option's name correctly.

* Drop the cloud builder's false matched User-Agent settings

The cloud builder's docstring listed max_matched_useragents_length,
misspelled, as ignored when update_matched_useragent is false, which the
C header contradicts. The cloud builder reads neither setting, so both
entries are removed rather than corrected.

The match metrics example comment now says the option is set to show
where to turn it off, as the line sets it to True.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Nightly fails when no package has changed since its last release

3 participants