Skip to content

Commit 485f02b

Browse files
committed
Merge branch 'main' into feat/metadata-content-type
* main: meta(client): Release setup (#157) feat(server): Improve error handling during shutdown (#161) feat: Allow defining a per-usecase/client default expiration policy (#158)
2 parents f608c3d + a31a374 commit 485f02b

File tree

14 files changed

+173
-21
lines changed

14 files changed

+173
-21
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Build Python client
2+
3+
on:
4+
push:
5+
branches:
6+
- release/**
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
build:
13+
name: Build and upload artifacts
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
20+
21+
- name: Build artifacts
22+
run: uv build --package objectstore-client
23+
24+
- uses: actions/upload-artifact@v5
25+
with:
26+
path: dist/*
27+
if-no-files-found: 'error'
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Release client libraries
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: Version to release
8+
required: true
9+
force:
10+
description: Force a release even when there are release-blockers (optional)
11+
required: false
12+
merge_target:
13+
description: Target branch to merge into. Uses the default branch as a fallback (optional)
14+
required: false
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
release:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
24+
id: token
25+
with:
26+
app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }}
27+
private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }}
28+
29+
- uses: actions/checkout@v5
30+
with:
31+
token: ${{ steps.token.outputs.token }}
32+
fetch-depth: 0
33+
34+
- uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2
35+
36+
- name: Prepare release
37+
uses: getsentry/action-prepare-release@v1
38+
env:
39+
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
40+
with:
41+
version: ${{ github.event.inputs.version }}
42+
force: ${{ github.event.inputs.force }}
43+
merge_target: ${{ github.event.inputs.merge_target }}
44+
path: clients

clients/.craft.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
changelogPolicy: auto
2+
preReleaseCommand: ../scripts/bump-version-clients.sh
3+
4+
targets:
5+
- name: github
6+
- name: crates
7+
- name: pypi
8+
- name: sentry-pypi
9+
internalPypiRepo: getsentry/pypi
10+
11+
requireNames:
12+
- /.*objectstore_client.*whl$/
13+
- /.*objectstore_client.*tar\.gz$/

clients/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Unreleased
2+
3+
This is the first release of the Objectstore client SDKs.

clients/python/LICENSE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../LICENSE.md

clients/python/pyproject.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
[project]
22
name = "objectstore-client"
33
version = "0.1.0"
4-
description = "Python client for the Sentry Objectstore service"
4+
description = "Client SDK for Objectstore, the Sentry object storage platform"
55
readme = "README.md"
6+
authors = [
7+
{name = "Sentry", email = "oss@sentry.io"},
8+
]
9+
homepage = "https://getsentry.github.io/objectstore/"
10+
repository = "https://github.com/getsentry/objectstore"
11+
license = { file = "LICENSE.md" }
612
requires-python = ">=3.13.1"
713
dependencies = [
814
"sentry-sdk>=2.42.1",

clients/python/src/objectstore_client/client.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,16 @@ def __init__(
4343
usecase: str,
4444
metrics_backend: MetricsBackend | None = None,
4545
propagate_traces: bool = False,
46+
default_expiration_policy: ExpirationPolicy | None = None,
4647
):
4748
self._base_url = objectstore_base_url
4849
self._usecase = usecase
4950
self._default_compression: Compression = "zstd"
51+
self._default_expiration_policy = (
52+
format_expiration(default_expiration_policy)
53+
if default_expiration_policy
54+
else None
55+
)
5056
self._propagate_traces = propagate_traces
5157
self._metrics_backend = metrics_backend or NoOpMetricsBackend()
5258

@@ -55,6 +61,7 @@ def _make_client(self, scope: str) -> Client:
5561
return Client(
5662
pool,
5763
self._default_compression,
64+
self._default_expiration_policy,
5865
self._usecase,
5966
scope,
6067
self._propagate_traces,
@@ -79,13 +86,15 @@ def __init__(
7986
self,
8087
pool: HTTPConnectionPool,
8188
default_compression: Compression,
89+
default_expiration_policy: str | None,
8290
usecase: str,
8391
scope: str,
8492
propagate_traces: bool,
8593
metrics_backend: MetricsBackend,
8694
):
8795
self._pool = pool
8896
self._default_compression = default_compression
97+
self._default_expiration_policy = default_expiration_policy
8998
self._usecase = usecase
9099
self._scope = scope
91100
self._propagate_traces = propagate_traces
@@ -140,6 +149,8 @@ def put(
140149

141150
if expiration_policy:
142151
headers[HEADER_EXPIRATION] = format_expiration(expiration_policy)
152+
elif self._default_expiration_policy:
153+
headers[HEADER_EXPIRATION] = self._default_expiration_policy
143154

144155
if metadata:
145156
for k, v in metadata.items():

clients/rust/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ authors = ["Sentry <oss@sentry.io>"]
44
description = "Client SDK for Objectstore, the Sentry object storage platform"
55
homepage = "https://getsentry.github.io/objectstore/"
66
repository = "https://github.com/getsentry/objectstore"
7-
license-file = "../LICENSE.md"
7+
license-file = "../../LICENSE.md"
88
version = "0.1.0"
99
edition = "2024"
1010
rust-version = "1.89"

clients/rust/src/client.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::sync::Arc;
33

44
use bytes::Bytes;
55
use futures_util::stream::BoxStream;
6+
use objectstore_types::ExpirationPolicy;
67
use reqwest::header::HeaderName;
78

89
pub use objectstore_types::{Compression, PARAM_SCOPE, PARAM_USECASE};
@@ -19,10 +20,11 @@ const USER_AGENT: &str = concat!("objectstore-client/", env!("CARGO_PKG_VERSION"
1920
pub struct ClientBuilder {
2021
service_url: Arc<str>,
2122
client: reqwest::Client,
23+
propagate_traces: bool,
2224

2325
usecase: Arc<str>,
2426
default_compression: Compression,
25-
propagate_traces: bool,
27+
default_expiration_policy: ExpirationPolicy,
2628
}
2729

2830
impl ClientBuilder {
@@ -47,10 +49,11 @@ impl ClientBuilder {
4749
Ok(Self {
4850
service_url: service_url.trim_end_matches('/').into(),
4951
client,
52+
propagate_traces: false,
5053

5154
usecase: usecase.into(),
5255
default_compression: Compression::Zstd,
53-
propagate_traces: false,
56+
default_expiration_policy: ExpirationPolicy::Manual,
5457
})
5558
}
5659

@@ -60,6 +63,12 @@ impl ClientBuilder {
6063
self
6164
}
6265

66+
/// This sets a default expiration policy used for uploads.
67+
pub fn default_expiration_policy(mut self, expiration_policy: ExpirationPolicy) -> Self {
68+
self.default_expiration_policy = expiration_policy;
69+
self
70+
}
71+
6372
/// This changes whether the `sentry-trace` header will be sent to Objectstore
6473
/// to take advantage of Sentry's distributed tracing.
6574
pub fn with_distributed_tracing(mut self, propagate_traces: bool) -> Self {
@@ -71,11 +80,12 @@ impl ClientBuilder {
7180
Client {
7281
service_url: self.service_url.clone(),
7382
http: self.client.clone(),
83+
propagate_traces: self.propagate_traces,
7484

7585
usecase: self.usecase.clone(),
7686
scope,
7787
default_compression: self.default_compression,
78-
propagate_traces: self.propagate_traces,
88+
default_expiration_policy: self.default_expiration_policy,
7989
}
8090
}
8191

@@ -98,6 +108,7 @@ impl ClientBuilder {
98108
pub struct Client {
99109
pub(crate) http: reqwest::Client,
100110
pub(crate) service_url: Arc<str>,
111+
propagate_traces: bool,
101112

102113
pub(crate) usecase: Arc<str>,
103114

@@ -113,8 +124,7 @@ pub struct Client {
113124
/// characters.
114125
pub(crate) scope: String,
115126
pub(crate) default_compression: Compression,
116-
117-
propagate_traces: bool,
127+
pub(crate) default_expiration_policy: ExpirationPolicy,
118128
}
119129

120130
/// The type of [`Stream`](futures_util::Stream) to be used for a PUT request.

clients/rust/src/put.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::{Client, ClientStream};
1818
impl Client {
1919
fn put_body(&self, body: PutBody) -> PutBuilder<'_> {
2020
let metadata = Metadata {
21+
expiration_policy: self.default_expiration_policy,
2122
compression: Some(self.default_compression),
2223
..Default::default()
2324
};

0 commit comments

Comments
 (0)