Skip to content

Commit bc99b84

Browse files
authored
Add Analytics API (#68)
* fetch & codegen * fix extra lifetime error * fix: use `oneOf` instead of `anyOf` * feat: analytics API * fix incorrect typesense options passed * feat: analytics events retrieve
1 parent 7011839 commit bc99b84

35 files changed

+770
-194
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
]
2626
services:
2727
typesense:
28-
image: typesense/typesense:30.0.rc26
28+
image: typesense/typesense:30.0.rca33
2929
ports:
3030
- 8108:8108/tcp
3131
volumes:
@@ -35,6 +35,8 @@ jobs:
3535
TYPESENSE_API_KEY: 'xyz'
3636
TYPESENSE_ENABLE_CORS: true
3737
TYPESENSE_URL: 'http://localhost:8108'
38+
TYPESENSE_ENABLE_SEARCH_ANALYTICS: 'true'
39+
TYPESENSE_ANALYTICS_DIR: '/analytics-data'
3840
steps:
3941
- uses: actions/checkout@v4
4042
- name: Cache .cargo and target

compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
services:
22
typesense:
3-
image: typesense/typesense:30.0.rc26
3+
image: typesense/typesense:30.0.rca33
44
restart: on-failure
55
ports:
66
- '8108:8108'
77
volumes:
88
- ./typesense-data:/data
9-
command: '--data-dir /data --api-key=xyz --enable-cors'
9+
command: '--data-dir /data --api-key=xyz --enable-cors --enable-search-analytics=true --analytics-dir=/analytics-data'

openapi.yml

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ paths:
502502
application/json:
503503
schema:
504504
$ref: "#/components/schemas/ApiResponse"
505-
505+
506506
put:
507507
tags:
508508
- synonyms
@@ -650,7 +650,7 @@ paths:
650650
content:
651651
application/json:
652652
schema:
653-
$ref: "#/components/schemas/SynonymItemSchema"
653+
$ref: "#/components/schemas/SynonymItemUpsertSchema"
654654
required: true
655655
responses:
656656
"200":
@@ -1647,7 +1647,7 @@ paths:
16471647
{"log-slow-requests-time-ms": 2000}
16481648
responses:
16491649
'200':
1650-
description: Compacting the on-disk database succeeded.
1650+
description: Toggle Slow Request Log database succeeded.
16511651
content:
16521652
application/json:
16531653
schema:
@@ -1805,7 +1805,7 @@ paths:
18051805
- $ref: "#/components/schemas/AnalyticsRule"
18061806
- type: array
18071807
items:
1808-
anyOf:
1808+
oneOf:
18091809
- $ref: "#/components/schemas/AnalyticsRule"
18101810
- type: object
18111811
properties:
@@ -3975,8 +3975,7 @@ components:
39753975
name:
39763976
type: string
39773977
type:
3978-
type: string
3979-
enum: [popular_queries, nohits_queries, counter, log]
3978+
$ref: "#/components/schemas/AnalyticsRuleType"
39803979
collection:
39813980
type: string
39823981
event_type:
@@ -4001,6 +4000,9 @@ components:
40014000
type: string
40024001
weight:
40034002
type: integer
4003+
AnalyticsRuleType:
4004+
type: string
4005+
enum: [popular_queries, nohits_queries, counter, log]
40044006
AnalyticsRuleUpdate:
40054007
type: object
40064008
description: Fields allowed to update on an analytics rule
@@ -4041,7 +4043,7 @@ components:
40414043
query_counter_events: { type: integer }
40424044
doc_log_events: { type: integer }
40434045
doc_counter_events: { type: integer }
4044-
4046+
40454047
APIStatsResponse:
40464048
type: object
40474049
properties:
@@ -4364,15 +4366,11 @@ components:
43644366
type: string
43654367
description: ID of the deleted NL search model
43664368

4367-
SynonymItemSchema:
4369+
SynonymItemUpsertSchema:
43684370
type: object
43694371
required:
4370-
- id
43714372
- synonyms
43724373
properties:
4373-
id:
4374-
type: string
4375-
description: Unique identifier for the synonym item
43764374
synonyms:
43774375
type: array
43784376
description: Array of words that should be considered as synonyms
@@ -4390,6 +4388,17 @@ components:
43904388
items:
43914389
type: string
43924390

4391+
SynonymItemSchema:
4392+
allOf:
4393+
- type: object
4394+
required:
4395+
- id
4396+
properties:
4397+
id:
4398+
type: string
4399+
description: Unique identifier for the synonym item
4400+
- $ref: "#/components/schemas/SynonymItemUpsertSchema"
4401+
43934402
SynonymSetCreateSchema:
43944403
type: object
43954404
required:

preprocessed_openapi.yml

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@ paths:
10361036
content:
10371037
application/json:
10381038
schema:
1039-
$ref: '#/components/schemas/SynonymItemSchema'
1039+
$ref: '#/components/schemas/SynonymItemUpsertSchema'
10401040
responses:
10411041
'200':
10421042
description: Synonym item successfully created/updated
@@ -2003,7 +2003,7 @@ paths:
20032003
x-rust-has-borrowed-data: true
20042004
responses:
20052005
'200':
2006-
description: Compacting the on-disk database succeeded.
2006+
description: Toggle Slow Request Log database succeeded.
20072007
content:
20082008
application/json:
20092009
schema:
@@ -2528,7 +2528,7 @@ paths:
25282528
- $ref: '#/components/schemas/AnalyticsRule'
25292529
- type: array
25302530
items:
2531-
anyOf:
2531+
oneOf:
25322532
- $ref: '#/components/schemas/AnalyticsRule'
25332533
- type: object
25342534
properties:
@@ -4441,12 +4441,7 @@ components:
44414441
name:
44424442
type: string
44434443
type:
4444-
type: string
4445-
enum:
4446-
- popular_queries
4447-
- nohits_queries
4448-
- counter
4449-
- log
4444+
$ref: '#/components/schemas/AnalyticsRuleType'
44504445
collection:
44514446
type: string
44524447
event_type:
@@ -4474,6 +4469,13 @@ components:
44744469
type: integer
44754470
x-rust-has-borrowed-data: true
44764471
x-rust-has-borrowed-data: true
4472+
AnalyticsRuleType:
4473+
type: string
4474+
enum:
4475+
- popular_queries
4476+
- nohits_queries
4477+
- counter
4478+
- log
44774479
AnalyticsRuleUpdate:
44784480
type: object
44794481
description: Fields allowed to update on an analytics rule
@@ -4859,15 +4861,11 @@ components:
48594861
id:
48604862
type: string
48614863
description: ID of the deleted NL search model
4862-
SynonymItemSchema:
4864+
SynonymItemUpsertSchema:
48634865
type: object
48644866
required:
4865-
- id
48664867
- synonyms
48674868
properties:
4868-
id:
4869-
type: string
4870-
description: Unique identifier for the synonym item
48714869
synonyms:
48724870
type: array
48734871
description: Array of words that should be considered as synonyms
@@ -4885,6 +4883,16 @@ components:
48854883
items:
48864884
type: string
48874885
x-rust-has-borrowed-data: true
4886+
SynonymItemSchema:
4887+
allOf:
4888+
- type: object
4889+
required:
4890+
- id
4891+
properties:
4892+
id:
4893+
type: string
4894+
description: Unique identifier for the synonym item
4895+
- $ref: '#/components/schemas/SynonymItemUpsertSchema'
48884896
SynonymSetCreateSchema:
48894897
type: object
48904898
required:
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//! Provides access to the API endpoint for posting analytics events.
2+
//!
3+
//! An `Events` instance is created via the `client.analytics().events()` method.
4+
5+
use crate::{Client, Error, execute_wrapper, models};
6+
use typesense_codegen::apis::analytics_api;
7+
8+
/// Provides methods for interacting with analytics events.
9+
///
10+
/// This struct is created by calling `client.analytics().events()`.
11+
pub struct Events<'a> {
12+
pub(super) client: &'a Client,
13+
}
14+
15+
impl<'a> Events<'a> {
16+
/// Creates a new `Events` instance.
17+
#[inline]
18+
pub(super) fn new(client: &'a Client) -> Self {
19+
Self { client }
20+
}
21+
22+
/// Posts an analytics event for tracking user behavior.
23+
///
24+
/// # Arguments
25+
/// * `schema` - An `AnalyticsEvent` object representing the event.
26+
pub async fn create(
27+
&self,
28+
schema: models::AnalyticsEvent<'_>,
29+
) -> Result<models::AnalyticsEventCreateResponse, Error<analytics_api::CreateAnalyticsEventError>>
30+
{
31+
let params = analytics_api::CreateAnalyticsEventParams {
32+
analytics_event: schema,
33+
};
34+
execute_wrapper!(self, analytics_api::create_analytics_event, params)
35+
}
36+
37+
/// Retrieve the most recent analytics events for a specific user and analytics rule name.
38+
///
39+
/// # Arguments
40+
/// * `params` - `GetAnalyticsEventsParams`.
41+
pub async fn retrieve(
42+
&self,
43+
params: models::GetAnalyticsEventsParams<'_>,
44+
) -> Result<models::AnalyticsEventsResponse, Error<analytics_api::GetAnalyticsEventsError>>
45+
{
46+
execute_wrapper!(self, analytics_api::get_analytics_events, params)
47+
}
48+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//! Provides access to the analytics API endpoints for managing rules and posting events.
2+
//!
3+
//! An `Analytics` instance is created via the main `client.analytics()` method.
4+
mod events;
5+
mod rule;
6+
mod rules;
7+
use crate::Client;
8+
use events::Events;
9+
use rule::Rule;
10+
use rules::Rules;
11+
12+
/// Provides methods for interacting with Typesense analytics rules and events.
13+
///
14+
/// This struct is created by calling `client.analytics()`.
15+
pub struct Analytics<'a> {
16+
pub(super) client: &'a Client,
17+
}
18+
19+
impl<'a> Analytics<'a> {
20+
/// Creates a new `Analytics` instance.
21+
#[inline]
22+
pub(super) fn new(client: &'a Client) -> Self {
23+
Self { client }
24+
}
25+
26+
/// Provides access to endpoints for managing a collection of analytics rules.
27+
#[inline]
28+
pub fn rules(&self) -> Rules<'a> {
29+
Rules::new(self.client)
30+
}
31+
32+
/// Provides access to endpoints for managing a single analytics rule.
33+
///
34+
/// # Arguments
35+
/// * `rule_name` - The name of the analytics rule to manage.
36+
#[inline]
37+
pub fn rule(&self, rule_name: &'a str) -> Rule<'a> {
38+
Rule::new(self.client, rule_name)
39+
}
40+
41+
/// Provides access to the endpoint for creating analytics events.
42+
#[inline]
43+
pub fn events(&self) -> Events<'a> {
44+
Events::new(self.client)
45+
}
46+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//! Provides access to the API endpoints for managing a single analytics rule.
2+
//!
3+
//! An `Rule` instance is created via the `client.analytics().rule("rule_name")` method.
4+
5+
use crate::{Client, Error, execute_wrapper, models};
6+
use typesense_codegen::apis::analytics_api;
7+
8+
/// Provides methods for interacting with a specific analytics rule.
9+
///
10+
/// This struct is created by calling `client.analytics().rule("rule_name")`.
11+
pub struct Rule<'a> {
12+
pub(super) client: &'a Client,
13+
pub(super) rule_name: &'a str,
14+
}
15+
16+
impl<'a> Rule<'a> {
17+
/// Creates a new `Rule` instance for a specific rule name.
18+
#[inline]
19+
pub(super) fn new(client: &'a Client, rule_name: &'a str) -> Self {
20+
Self { client, rule_name }
21+
}
22+
23+
/// Retrieves the details of this specific analytics rule.
24+
pub async fn retrieve(
25+
&self,
26+
) -> Result<models::AnalyticsRule, Error<analytics_api::RetrieveAnalyticsRuleError>> {
27+
let params = analytics_api::RetrieveAnalyticsRuleParams {
28+
rule_name: self.rule_name.into(),
29+
};
30+
execute_wrapper!(self, analytics_api::retrieve_analytics_rule, params)
31+
}
32+
33+
/// Permanently deletes this specific analytics rule.
34+
pub async fn delete(
35+
&self,
36+
) -> Result<models::AnalyticsRule, Error<analytics_api::DeleteAnalyticsRuleError>> {
37+
let params = analytics_api::DeleteAnalyticsRuleParams {
38+
rule_name: self.rule_name.into(),
39+
};
40+
execute_wrapper!(self, analytics_api::delete_analytics_rule, params)
41+
}
42+
}

0 commit comments

Comments
 (0)