Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@

This is the current release cycle, so stay tuned for future releases!

### v3.4.3

- **Add a plugin version API endpoint.**
The endpoint `/plugins/{name}/version` now returns a plugin's version string.

- **Hide login warning on plugin updater thread.**
The plugins updater thread no longer will raise a login warning.

- **Add precision kwarg aliases to `get_current_timestamp()`.**
You may now treat `Pipe.precision` as kwargs for `get_current_timestamp()`:

```python
import meerschaum as mrsm
from meerschaum.utils.dtypes import get_current_timestamp

pipe = mrsm.Pipe(
'demo', 'precision', 'timestamp', instance='sql:local',
precision={'unit': 's', 'interval': 30},
)
now = get_current_timestamp(**pipe.precision)
print(now)
# 2026-06-23 04:30:30+00:00
```

### v3.4.2

- **Run inline Python with `mrsm python -c`.**
Expand Down
24 changes: 24 additions & 0 deletions docs/zensical/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8241,6 +8241,30 @@ Source: https://meerschaum.io/news/changelog/

This is the current release cycle, so stay tuned for future releases!

### v3.4.3

- **Add a plugin version API endpoint.**
The endpoint `/plugins/{name}/version` now returns a plugin's version string.

- **Hide login warning on plugin updater thread.**
The plugins updater thread no longer will raise a login warning.

- **Add precision kwarg aliases to `get_current_timestamp()`.**
You may now treat `Pipe.precision` as kwargs for `get_current_timestamp()`:

```python
import meerschaum as mrsm
from meerschaum.utils.dtypes import get_current_timestamp

pipe = mrsm.Pipe(
'demo', 'precision', 'timestamp', instance='sql:local',
precision={'unit': 's', 'interval': 30},
)
now = get_current_timestamp(**pipe.precision)
print(now)
# 2026-06-23 04:30:30+00:00
```

### v3.4.2

- **Run inline Python with `mrsm python -c`.**
Expand Down
24 changes: 24 additions & 0 deletions docs/zensical/news/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,30 @@

This is the current release cycle, so stay tuned for future releases!

### v3.4.3

- **Add a plugin version API endpoint.**
The endpoint `/plugins/{name}/version` now returns a plugin's version string.

- **Hide login warning on plugin updater thread.**
The plugins updater thread no longer will raise a login warning.

- **Add precision kwarg aliases to `get_current_timestamp()`.**
You may now treat `Pipe.precision` as kwargs for `get_current_timestamp()`:

```python
import meerschaum as mrsm
from meerschaum.utils.dtypes import get_current_timestamp

pipe = mrsm.Pipe(
'demo', 'precision', 'timestamp', instance='sql:local',
precision={'unit': 's', 'interval': 30},
)
now = get_current_timestamp(**pipe.precision)
print(now)
# 2026-06-23 04:30:30+00:00
```

### v3.4.2

- **Run inline Python with `mrsm python -c`.**
Expand Down
12 changes: 7 additions & 5 deletions meerschaum/_internal/shell/updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,19 +164,21 @@ def _get_remote_plugin_version(
name: str,
repo_keys: str,
debug: bool = False,
) -> Optional[str]:
) -> Union[str, None]:
"""Return the latest version of a plugin from its origin repository."""
try:
from meerschaum.core import Plugin
from meerschaum.connectors.parse import parse_repo_keys
conn = parse_repo_keys(repo_keys)
_warn = conn.__dict__.pop('_warn', None)
conn._warn = False
plugin = Plugin(name, repo=repo_keys)
attributes = conn.get_plugin_attributes(plugin, debug=debug)
version = conn.get_plugin_version(plugin, debug=debug)
if _warn is not None:
conn._warn = _warn
except Exception:
return None
if not isinstance(attributes, dict):
return None
return attributes.get('version')
return version


def run_version_check_thread(debug: bool = False) -> Union[Thread, None]:
Expand Down
23 changes: 18 additions & 5 deletions meerschaum/api/routes/_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
import pathlib
import os

import meerschaum as mrsm
from meerschaum.core import User
from meerschaum.utils.typing import Optional, List, SuccessTuple, Any, Dict
from meerschaum.utils.typing import Optional, List, SuccessTuple, Any, Dict, Union

from meerschaum.api import (
fastapi,
Expand All @@ -24,7 +23,6 @@
manager,
debug,
private,
no_auth,
default_instance_keys,
ScopedAuth,
)
Expand Down Expand Up @@ -110,7 +108,11 @@ def register_plugin(

if curr_user is not None:
plugin_user_id = get_api_connector(PLUGINS_INSTANCE_KEYS).get_plugin_user_id(plugin, debug=debug)
curr_user_id = get_api_connector(PLUGINS_INSTANCE_KEYS).get_user_id(curr_user, debug=debug) if curr_user is not None else -1
curr_user_id = (
get_api_connector(PLUGINS_INSTANCE_KEYS).get_user_id(curr_user, debug=debug)
if curr_user is not None
else -1
)
if plugin_user_id is not None and plugin_user_id != curr_user_id:
return False, f"User '{curr_user.username}' cannot edit plugin '{plugin}'."
plugin.user_id = curr_user_id
Expand Down Expand Up @@ -154,7 +156,18 @@ def get_plugin_attributes(
"""
Get a plugin's attributes.
"""
return get_api_connector(PLUGINS_INSTANCE_KEYS).get_plugin_attributes(Plugin(name))
return get_api_connector(PLUGINS_INSTANCE_KEYS).get_plugin_attributes(Plugin(name), debug=debug)


@app.get(plugins_endpoint + '/{name}/version')
def get_plugin_version(
name: str,
curr_user = fastapi.Depends(ScopedAuth(['plugins:read'])) if private else None,
) -> Union[str, None]:
"""
Get a plugin's version.
"""
return get_api_connector(PLUGINS_INSTANCE_KEYS).get_plugin_version(Plugin(name), debug=debug) or None


@app.get(plugins_endpoint, tags=['Plugins'])
Expand Down
2 changes: 1 addition & 1 deletion meerschaum/config/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Specify the Meerschaum release version.
"""

__version__ = "3.4.2"
__version__ = "3.4.3"
1 change: 1 addition & 0 deletions meerschaum/connectors/api/_APIConnector.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class APIConnector(InstanceConnector):
delete_plugin,
get_plugins,
get_plugin_attributes,
get_plugin_version,
)
from ._login import login, test_connection
from ._users import (
Expand Down
2 changes: 2 additions & 0 deletions meerschaum/connectors/api/_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def login(
**kw: Any
) -> SuccessTuple:
"""Log in and set the session token."""
if warn and self.__dict__.get('_warn', None) is False:
warn = False
if self.login_scheme == 'api_key':
validate_response = self.post(
STATIC_CONFIG['api']['endpoints']['tokens'] + '/validate',
Expand Down
21 changes: 21 additions & 0 deletions meerschaum/connectors/api/_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,27 @@ def get_plugin_attributes(
return attributes


def get_plugin_version(
self,
plugin: mrsm.core.Plugin,
debug: bool = False
) -> Union[str, None]:
"""
Return a plugin's version.
"""
from meerschaum.utils.warnings import warn
r_url = plugin_r_url(plugin) + '/version'
response = self.get(r_url, use_token=True, debug=debug)
if not response:
return None
try:
version = response.json()
except Exception as e:
warn(f"Cannot parse version for {plugin}:\n{e}")
version = None
return version or None


def delete_plugin(
self,
plugin: mrsm.core.Plugin,
Expand Down
15 changes: 15 additions & 0 deletions meerschaum/utils/dtypes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,8 @@ def get_current_timestamp(
round_to: str = 'down',
as_pandas: bool = False,
as_int: bool = False,
unit: str = _STATIC_CONFIG['dtypes']['datetime']['default_precision_unit'],
interval: int = 1,
_now: Union[datetime, int, None] = None,
) -> 'Union[datetime, pd.Timestamp, int]':
"""
Expand Down Expand Up @@ -1176,6 +1178,12 @@ def get_current_timestamp(
If `True`, return the timestamp to an integer.
Overrides `as_pandas`.

unit: str, default 'us'
Alias for `precision_unit`.

interval: int, default 1
Alias for `precision_interval`.

Returns
-------
A Pandas Timestamp, datetime object, or integer with precision to the provided unit.
Expand All @@ -1187,6 +1195,13 @@ def get_current_timestamp(
>>> get_current_timestamp('ms')
Timestamp('2025-07-17 17:59:16.424000+0000', tz='UTC')
"""
default_unit = _STATIC_CONFIG['dtypes']['datetime']['default_precision_unit']
if unit != precision_unit and precision_unit == default_unit:
precision_unit = unit

if interval != precision_interval and precision_interval == 1:
precision_interval = interval

true_precision_unit = MRSM_PRECISION_UNITS_ALIASES.get(precision_unit, precision_unit)
if true_precision_unit not in MRSM_PRECISION_UNITS_SCALARS:
from meerschaum.utils.misc import items_str
Expand Down
Loading